Fixes to tcp and to the ipv4endpointdemux to allow forking to work correctly
This commit is contained in:
@@ -83,9 +83,9 @@ void PacketSink::StartApplication() // Called at time specified by Start
|
||||
|
||||
m_socket->SetRecvCallback (MakeCallback(&PacketSink::Receive, this));
|
||||
m_socket->SetAcceptCallback (
|
||||
MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
|
||||
MakeCallback (&PacketSink::AcceptConnectionRequest, this),
|
||||
MakeNullCallback<void, Ptr<Socket>, const Address&> (),
|
||||
MakeCallback(&PacketSink::CloseConnection, this) );
|
||||
MakeCallback (&PacketSink::CloseConnection, this) );
|
||||
}
|
||||
|
||||
void PacketSink::StopApplication() // Called at time specified by Stop
|
||||
@@ -116,6 +116,11 @@ void PacketSink::CloseConnection (Ptr<Socket> socket)
|
||||
socket->Close ();
|
||||
}
|
||||
|
||||
bool PacketSink::AcceptConnectionRequest (Ptr<Socket> socket, const Address &from)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Ptr<TraceResolver>
|
||||
PacketSink::GetTraceResolver (void) const
|
||||
{
|
||||
|
||||
@@ -79,6 +79,7 @@ private:
|
||||
|
||||
virtual void Receive (Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
|
||||
virtual void CloseConnection (Ptr<Socket> socket);
|
||||
virtual bool AcceptConnectionRequest (Ptr<Socket> socket, const Address &from);
|
||||
|
||||
Ptr<Socket> m_socket; // Associated socket
|
||||
Address m_local; // Local address to bind to
|
||||
|
||||
@@ -185,10 +185,11 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
|
||||
Ptr<Ipv4Interface> incomingInterface)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
uint32_t genericity = 3;
|
||||
Ipv4EndPoint *generic = 0;
|
||||
EndPoints retval;
|
||||
|
||||
EndPoints retval1; // Matches exact on local port, wildcards on others
|
||||
EndPoints retval2; // Matches exact on local port/adder, wildcards on others
|
||||
EndPoints retval3; // Matches all but local address
|
||||
EndPoints retval4; // Exact match on all 4
|
||||
|
||||
//NS_LOG_PARAMS (this << daddr << dport << saddr << sport);
|
||||
NS_LOG_PARAMS_BEGIN ();
|
||||
NS_LOG_PARAM (this);
|
||||
@@ -198,9 +199,106 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
|
||||
NS_LOG_PARAM (sport);
|
||||
NS_LOG_PARAM (incomingInterface);
|
||||
NS_LOG_PARAMS_END ();
|
||||
|
||||
NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
|
||||
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
|
||||
{
|
||||
Ipv4EndPoint* endP = *i;
|
||||
NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
|
||||
<< " daddr=" << endP->GetLocalAddress ()
|
||||
<< " sport=" << endP->GetPeerPort ()
|
||||
<< " saddr=" << endP->GetPeerAddress ());
|
||||
if (endP->GetLocalPort () != dport)
|
||||
{
|
||||
NS_LOG_LOGIC ("Skipping endpoint " << &endP
|
||||
<< " because endpoint dport "
|
||||
<< endP->GetLocalPort ()
|
||||
<< " does not match packet dport " << dport);
|
||||
continue;
|
||||
}
|
||||
bool isBroadcast = (daddr.IsBroadcast () ||
|
||||
daddr.IsSubnetDirectedBroadcast (
|
||||
incomingInterface->GetNetworkMask ()));
|
||||
Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress ();
|
||||
NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast
|
||||
<< " localInterface="<< endP->GetLocalInterface ());
|
||||
bool localAddressMatchesWildCard =
|
||||
(endP->GetLocalAddress() == Ipv4Address::GetAny()) &&
|
||||
(endP->GetLocalInterface() == Ipv4Address::GetAny());
|
||||
bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
|
||||
|
||||
if (isBroadcast)
|
||||
{
|
||||
std::cout << "Found bcast, localaddr " << endP->GetLocalAddress()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if (isBroadcast && (endP->GetLocalAddress() != Ipv4Address::GetAny()))
|
||||
{
|
||||
localAddressMatchesExact = (endP->GetLocalAddress () ==
|
||||
incomingInterfaceAddr);
|
||||
}
|
||||
// if no match here, keep looking
|
||||
if (!(localAddressMatchesExact || localAddressMatchesWildCard))
|
||||
continue;
|
||||
bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
|
||||
bool remotePeerMatchesWildCard = endP->GetPeerPort() == 0;
|
||||
bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
|
||||
bool remoteAddressMatchesWildCard = endP->GetPeerAddress () ==
|
||||
Ipv4Address::GetAny();
|
||||
// If remote does not match either with exact or wildcard,
|
||||
// skip this one
|
||||
if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
|
||||
continue;
|
||||
if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
|
||||
continue;
|
||||
|
||||
// Now figure out which return list to add this one to
|
||||
if (localAddressMatchesWildCard &&
|
||||
remotePeerMatchesWildCard &&
|
||||
remoteAddressMatchesWildCard)
|
||||
{ // Only local port matches exactly
|
||||
retval1.push_back(endP);
|
||||
}
|
||||
if ((localAddressMatchesExact || ((isBroadcast && localAddressMatchesWildCard)))&&
|
||||
remotePeerMatchesWildCard &&
|
||||
remoteAddressMatchesWildCard)
|
||||
{ // Only local port and local address matches exactly
|
||||
retval2.push_back(endP);
|
||||
}
|
||||
if (localAddressMatchesWildCard &&
|
||||
remotePeerMatchesExact &&
|
||||
remoteAddressMatchesExact)
|
||||
{ // All but local address
|
||||
retval3.push_back(endP);
|
||||
}
|
||||
if (localAddressMatchesExact &&
|
||||
remotePeerMatchesExact &&
|
||||
remoteAddressMatchesExact)
|
||||
{ // All 4 match
|
||||
retval4.push_back(endP);
|
||||
}
|
||||
}
|
||||
|
||||
// Here we find the most exact match
|
||||
// first some debug
|
||||
#ifdef JUST_DEBUG
|
||||
if (!retval4.empty()) std::cout << "Matches 4" << std::endl;
|
||||
else if (!retval3.empty()) std::cout << "Matches 3" << std::endl;
|
||||
else if (!retval2.empty()) std::cout << "Matches 2" << std::endl;
|
||||
else if (!retval1.empty()) std::cout << "Matches 1" << std::endl;
|
||||
#endif
|
||||
// end debug
|
||||
if (!retval4.empty()) return retval4;
|
||||
if (!retval3.empty()) return retval3;
|
||||
if (!retval2.empty()) return retval2;
|
||||
return retval1; // might be empty if no matches
|
||||
|
||||
#ifdef REMOVE_FOR_TESTING
|
||||
uint32_t genericity = 3;
|
||||
Ipv4EndPoint *generic = 0;
|
||||
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
|
||||
{
|
||||
//Ipv4EndPoint* endP = *i;
|
||||
NS_LOG_DEBUG ("Looking at endpoint dport=" << (*i)->GetLocalPort ()
|
||||
<< " daddr=" << (*i)->GetLocalAddress ()
|
||||
<< " sport=" << (*i)->GetPeerPort ()
|
||||
@@ -271,6 +369,7 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
|
||||
retval.push_back (generic);
|
||||
}
|
||||
return retval;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
|
||||
|
||||
@@ -177,7 +178,7 @@ TcpStateMachine::TcpStateMachine()
|
||||
aT[FIN_WAIT_2][APP_LISTEN] = SA (CLOSED, RST_TX);
|
||||
aT[FIN_WAIT_2][APP_CONNECT] = SA (CLOSED, RST_TX);
|
||||
aT[FIN_WAIT_2][APP_SEND] = SA (CLOSED, RST_TX);
|
||||
aT[FIN_WAIT_2][SEQ_RECV] = SA (FIN_WAIT_2, NO_ACT);
|
||||
aT[FIN_WAIT_2][SEQ_RECV] = SA (FIN_WAIT_2, NEW_SEQ_RX);
|
||||
aT[FIN_WAIT_2][APP_CLOSE] = SA (FIN_WAIT_2, NO_ACT);
|
||||
aT[FIN_WAIT_2][TIMEOUT] = SA (FIN_WAIT_2, NO_ACT);
|
||||
aT[FIN_WAIT_2][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK);
|
||||
@@ -341,7 +342,7 @@ Ptr<Socket>
|
||||
TcpL4Protocol::CreateSocket (void)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
Ptr<Socket> socket = Create<TcpSocket> (m_node, this);
|
||||
Ptr<Socket> socket = CreateObject<TcpSocket> (m_node, this);
|
||||
return socket;
|
||||
}
|
||||
|
||||
@@ -408,6 +409,11 @@ TcpL4Protocol::Receive (Ptr<Packet> packet,
|
||||
TcpHeader tcpHeader;
|
||||
//these two do a peek, so that the packet can be forwarded up
|
||||
packet->RemoveHeader (tcpHeader);
|
||||
NS_LOG_LOGIC("TcpL4Protocol " << this
|
||||
<< " receiving seq " << tcpHeader.GetSequenceNumber()
|
||||
<< " ack " << tcpHeader.GetAckNumber()
|
||||
<< " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec
|
||||
<< " data size " << packet->GetSize());
|
||||
packet->AddHeader (tcpHeader);
|
||||
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
|
||||
Ipv4EndPointDemux::EndPoints endPoints =
|
||||
@@ -463,6 +469,11 @@ void
|
||||
TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader,
|
||||
Ipv4Address saddr, Ipv4Address daddr)
|
||||
{
|
||||
NS_LOG_LOGIC("TcpL4Protocol " << this
|
||||
<< " sending seq " << outgoingHeader.GetSequenceNumber()
|
||||
<< " ack " << outgoingHeader.GetAckNumber()
|
||||
<< " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec
|
||||
<< " data size " << packet->GetSize());
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAMS (this << packet << saddr << daddr);
|
||||
// XXX outgoingHeader cannot be logged
|
||||
|
||||
@@ -84,8 +84,8 @@ TcpSocket::TcpSocket(const TcpSocket& sock)
|
||||
m_endPoint (0),
|
||||
m_node (sock.m_node),
|
||||
m_tcp (sock.m_tcp),
|
||||
m_defaultAddress (sock.m_defaultAddress),
|
||||
m_defaultPort (sock.m_defaultPort),
|
||||
m_remoteAddress (sock.m_remoteAddress),
|
||||
m_remotePort (sock.m_remotePort),
|
||||
m_localAddress (sock.m_localAddress),
|
||||
m_localPort (sock.m_localPort),
|
||||
m_errno (sock.m_errno),
|
||||
@@ -266,15 +266,15 @@ TcpSocket::Close (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Actions_t action = ProcessEvent (APP_CLOSE);
|
||||
if (m_pendingData)
|
||||
{
|
||||
if (action == FIN_TX && m_pendingData->Size () != 0 )
|
||||
{
|
||||
m_closeOnEmpty = true;
|
||||
return 0;
|
||||
}
|
||||
if (m_pendingData && m_pendingData->Size() != 0)
|
||||
{ // App close with pending data must wait until all data transmitted
|
||||
m_closeOnEmpty = true;
|
||||
NS_LOG_LOGIC("Socket " << this <<
|
||||
" deferring close, state " << m_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Actions_t action = ProcessEvent (APP_CLOSE);
|
||||
ProcessAction (action);
|
||||
ShutdownSend ();
|
||||
return 0;
|
||||
@@ -295,13 +295,13 @@ TcpSocket::Connect (const Address & address)
|
||||
NS_ASSERT (m_endPoint != 0);
|
||||
}
|
||||
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
||||
m_defaultAddress = transport.GetIpv4 ();
|
||||
m_defaultPort = transport.GetPort ();
|
||||
m_remoteAddress = transport.GetIpv4 ();
|
||||
m_remotePort = transport.GetPort ();
|
||||
|
||||
uint32_t localIfIndex;
|
||||
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
|
||||
|
||||
if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
|
||||
if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
|
||||
{
|
||||
m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
|
||||
}
|
||||
@@ -321,30 +321,8 @@ TcpSocket::Connect (const Address & address)
|
||||
}
|
||||
int
|
||||
TcpSocket::Send (const Ptr<Packet> p) //p here is just data, no headers
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAMS (this << p);
|
||||
if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
|
||||
{ // Ok to buffer some data to send
|
||||
if (!m_pendingData)
|
||||
{
|
||||
m_pendingData = new PendingData (0); // Create if non-existent
|
||||
m_firstPendingSequence = m_nextTxSequence; // Note seq of first
|
||||
}
|
||||
//PendingData::Add always copies the data buffer, never modifies
|
||||
m_pendingData->Add (p->GetSize (), p->PeekData ());
|
||||
Actions_t action = ProcessEvent (APP_SEND);
|
||||
if (!ProcessAction (action))
|
||||
{
|
||||
return -1; // Failed, return zero
|
||||
}
|
||||
return p->GetSize ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errno = ERROR_NOTCONN;
|
||||
return -1;
|
||||
}
|
||||
{ // 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)
|
||||
@@ -360,7 +338,10 @@ int TcpSocket::Send (const uint8_t* buf, uint32_t size)
|
||||
}
|
||||
//PendingData::Add always copies the data buffer, never modifies
|
||||
m_pendingData->Add (size,buf);
|
||||
NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() <<
|
||||
" state " << m_state);
|
||||
Actions_t action = ProcessEvent (APP_SEND);
|
||||
NS_LOG_DEBUG(" action " << action);
|
||||
if (!ProcessAction (action))
|
||||
{
|
||||
return -1; // Failed, return zero
|
||||
@@ -437,6 +418,12 @@ TcpSocket::Listen (uint32_t q)
|
||||
void
|
||||
TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
|
||||
{
|
||||
NS_LOG_DEBUG("Socket " << this << " got forward up" <<
|
||||
" dport " << m_endPoint->GetLocalPort() <<
|
||||
" daddr " << m_endPoint->GetLocalAddress() <<
|
||||
" sport " << m_endPoint->GetPeerPort() <<
|
||||
" saddr " << m_endPoint->GetPeerAddress());
|
||||
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAMS (this << packet << ipv4 << port);
|
||||
if (m_shutdownRecv)
|
||||
@@ -458,6 +445,9 @@ TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
|
||||
Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
|
||||
Actions_t action = ProcessEvent (event); //updates the state
|
||||
Address address = InetSocketAddress (ipv4, port);
|
||||
NS_LOG_DEBUG("Socket " << this <<
|
||||
" processing pkt action, " << action <<
|
||||
" current state " << m_state);
|
||||
ProcessPacketAction (action, packet, tcpHeader, address);
|
||||
}
|
||||
|
||||
@@ -489,9 +479,10 @@ Actions_t TcpSocket::ProcessEvent (Events_t e)
|
||||
// this means the application side has completed its portion of
|
||||
// the handshaking
|
||||
{
|
||||
NotifyConnectionSucceeded ();
|
||||
Simulator::ScheduleNow(&TcpSocket::ConnectionSucceeded, this);
|
||||
//NotifyConnectionSucceeded ();
|
||||
m_connected = true;
|
||||
m_endPoint->SetPeer (m_defaultAddress, m_defaultPort);
|
||||
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
|
||||
NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
|
||||
}
|
||||
|
||||
@@ -523,10 +514,10 @@ void TcpSocket::SendEmptyPacket (uint8_t flags)
|
||||
header.SetSequenceNumber (m_nextTxSequence);
|
||||
header.SetAckNumber (m_nextRxSequence);
|
||||
header.SetSourcePort (m_endPoint->GetLocalPort ());
|
||||
header.SetDestinationPort (m_defaultPort);
|
||||
header.SetDestinationPort (m_remotePort);
|
||||
header.SetWindowSize (m_advertisedWindowSize);
|
||||
m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
|
||||
m_defaultAddress);
|
||||
m_remoteAddress);
|
||||
Time rto = m_rtt->RetransmitTimeout ();
|
||||
if (flags & TcpHeader::SYN)
|
||||
{
|
||||
@@ -632,56 +623,46 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
{
|
||||
case SYN_ACK_TX:
|
||||
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
|
||||
m_defaultPort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
|
||||
m_defaultAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
|
||||
if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
|
||||
{
|
||||
m_localAddress = ipv4->GetAddress (localIfIndex);
|
||||
}
|
||||
// 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
|
||||
{
|
||||
//this isn't a smart pointer because if it were it'd go out of scope and
|
||||
//get deleted; since execution will get back to this socket, it will
|
||||
//eventually get passed back up to the application as a smart pointer
|
||||
TcpSocket* newSock = new TcpSocket(*this);
|
||||
//Ptr<TcpSocket> newSock = Create<TcpSocket>(*this);
|
||||
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);
|
||||
//the cloned socket with be in listen state, so manually change state
|
||||
newSock->m_state = SYN_RCVD;
|
||||
//this listening socket should do nothing more
|
||||
return newSock->ProcessPacketAction(SYN_ACK_TX, p, tcpHeader, fromAddress);
|
||||
Simulator::ScheduleNow (&TcpSocket::CompleteFork, newSock,
|
||||
p, tcpHeader,fromAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_endPoint) //no endpoint means this a cloned socket due to SYN_RX
|
||||
{
|
||||
//equivalent to Bind
|
||||
m_endPoint = m_tcp->Allocate (m_localAddress,
|
||||
m_localPort,
|
||||
m_defaultAddress,
|
||||
m_defaultPort,
|
||||
Ipv4Address::GetAny()
|
||||
);
|
||||
//equivalent to FinishBind
|
||||
m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, this));
|
||||
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_endPoint->SetPeer (m_defaultAddress, m_defaultPort);
|
||||
if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
|
||||
{
|
||||
m_localAddress = ipv4->GetAddress (localIfIndex);
|
||||
m_endPoint->SetLocalAddress (m_localAddress);
|
||||
}
|
||||
}
|
||||
// TCP SYN consumes one byte
|
||||
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
|
||||
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
|
||||
// This is the cloned endpoint
|
||||
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
|
||||
if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
|
||||
{
|
||||
m_localAddress = ipv4->GetAddress (localIfIndex);
|
||||
m_endPoint->SetLocalAddress (m_localAddress);
|
||||
// Leave local addr in the portmap to any, as the path from
|
||||
// remote can change and packets can arrive on different interfaces
|
||||
//m_endPoint->SetLocalAddress (Ipv4Address::GetAny());
|
||||
}
|
||||
// TCP SYN consumes one byte
|
||||
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
|
||||
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
|
||||
break;
|
||||
case ACK_TX_1:
|
||||
NS_LOG_LOGIC ("TcpSocket " << this <<" Action ACK_TX_1");
|
||||
// TCP SYN consumes one byte
|
||||
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
|
||||
NS_LOG_DEBUG ("TcpSocket " << this << " ACK_TX_1" <<
|
||||
" nextRxSeq " << m_nextRxSequence);
|
||||
SendEmptyPacket (TcpHeader::ACK);
|
||||
m_rxWindowSize = tcpHeader.GetWindowSize ();
|
||||
m_nextTxSequence = tcpHeader.GetAckNumber ();
|
||||
@@ -710,7 +691,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_TX");
|
||||
NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_SEQ_RX");
|
||||
NewRx (p, tcpHeader, fromAddress); // Process new data received
|
||||
break;
|
||||
case PEER_CLOSE:
|
||||
@@ -740,7 +721,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
{
|
||||
NS_LOG_LOGIC ("TCP " << this
|
||||
<< " calling AppCloseRequest");
|
||||
NotifyCloseRequested ();
|
||||
NotifyHalfClose ();
|
||||
m_closeRequestNotified = true;
|
||||
}
|
||||
NS_LOG_LOGIC ("TcpSocket " << this
|
||||
@@ -763,7 +744,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
|
||||
NotifyNewConnectionCreated (this, fromAddress);
|
||||
m_connected = true; // ! This is bogus; fix when we clone the tcp
|
||||
m_endPoint->SetPeer (m_defaultAddress, m_defaultPort);
|
||||
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
|
||||
//treat the connection orientation final ack as a newack
|
||||
CommonNewAck (tcpHeader.GetAckNumber (), true);
|
||||
break;
|
||||
@@ -773,6 +754,33 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
return true;
|
||||
}
|
||||
|
||||
void TcpSocket::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
|
||||
{
|
||||
// Get port and address from peer (connecting host)
|
||||
m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
|
||||
m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
|
||||
m_endPoint = m_tcp->Allocate (m_localAddress,
|
||||
m_localPort,
|
||||
m_remoteAddress,
|
||||
m_remotePort,
|
||||
Ipv4Address::GetAny()
|
||||
);
|
||||
//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, this));
|
||||
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, this));
|
||||
ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
|
||||
NotifyNewConnectionCreated(this, fromAddress);
|
||||
}
|
||||
|
||||
void TcpSocket::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)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
@@ -827,7 +835,7 @@ bool TcpSocket::SendPendingData (bool withAck)
|
||||
header.SetSequenceNumber (m_nextTxSequence);
|
||||
header.SetAckNumber (m_nextRxSequence);
|
||||
header.SetSourcePort (m_endPoint->GetLocalPort());
|
||||
header.SetDestinationPort (m_defaultPort);
|
||||
header.SetDestinationPort (m_remotePort);
|
||||
if (m_shutdownSend)
|
||||
{
|
||||
m_errno = ERROR_SHUTDOWN;
|
||||
@@ -845,7 +853,7 @@ bool TcpSocket::SendPendingData (bool withAck)
|
||||
NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
|
||||
m_tcp->SendPacket (p, header,
|
||||
m_endPoint->GetLocalAddress (),
|
||||
m_defaultAddress);
|
||||
m_remoteAddress);
|
||||
m_rtt->SentSeq(m_nextTxSequence, sz); // notify the RTT
|
||||
// Notify the application
|
||||
Simulator::ScheduleNow(&TcpSocket::NotifyDataSent, this, p->GetSize ());
|
||||
@@ -896,7 +904,15 @@ void TcpSocket::NewRx (Ptr<Packet> p,
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAMS (this << p << "tcpHeader " << fromAddress);
|
||||
NS_LOG_LOGIC ("TcpSocket " << this << " NewRx, p.size is " << p->GetSize () );
|
||||
NS_LOG_LOGIC ("TcpSocket " << this << " NewRx,"
|
||||
<< " seq " << tcpHeader.GetSequenceNumber()
|
||||
<< " ack " << tcpHeader.GetAckNumber()
|
||||
<< " p.size is " << p->GetSize () );
|
||||
NS_LOG_DEBUG ("TcpSocket " << this <<
|
||||
" NewRx," <<
|
||||
" seq " << tcpHeader.GetSequenceNumber() <<
|
||||
" ack " << tcpHeader.GetAckNumber() <<
|
||||
" p.size is " << p->GetSize());
|
||||
States_t origState = m_state;
|
||||
uint32_t s = p->GetSize (); // Size of associated data
|
||||
if (s == 0)
|
||||
@@ -918,7 +934,7 @@ void TcpSocket::NewRx (Ptr<Packet> p,
|
||||
m_nextRxSequence += s; // Advance next expected sequence
|
||||
//bytesReceived += s; // Statistics
|
||||
NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
|
||||
NotifyDataReceived (p, fromAddress);
|
||||
NotifyDataReceived (p, fromAddress);
|
||||
if (m_closeNotified)
|
||||
{
|
||||
NS_LOG_LOGIC ("Tcp " << this << " HuH? Got data after closeNotif");
|
||||
@@ -1046,6 +1062,11 @@ void TcpSocket::CommonNewAck (SequenceNumber ack, bool skipTimer)
|
||||
SendPendingData();
|
||||
}
|
||||
|
||||
Ptr<TcpSocket> TcpSocket::Copy ()
|
||||
{
|
||||
return CreateObject<TcpSocket> (*this);
|
||||
}
|
||||
|
||||
void TcpSocket::NewAck (SequenceNumber seq)
|
||||
{ // New acknowledgement up to sequence number "seq"
|
||||
// Adjust congestion window in response to new ack's received
|
||||
@@ -1179,12 +1200,12 @@ void TcpSocket::Retransmit ()
|
||||
tcpHeader.SetSequenceNumber (m_nextTxSequence);
|
||||
tcpHeader.SetAckNumber (m_nextRxSequence);
|
||||
tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
|
||||
tcpHeader.SetDestinationPort (m_defaultPort);
|
||||
tcpHeader.SetDestinationPort (m_remotePort);
|
||||
tcpHeader.SetFlags (flags);
|
||||
tcpHeader.SetWindowSize (m_advertisedWindowSize);
|
||||
|
||||
m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
|
||||
m_defaultAddress);
|
||||
m_remoteAddress);
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
@@ -80,7 +80,9 @@ private:
|
||||
const Address& fromAddress);
|
||||
Actions_t ProcessEvent (Events_t e);
|
||||
bool SendPendingData(bool withAck = false);
|
||||
|
||||
void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress);
|
||||
void ConnectionSucceeded();
|
||||
|
||||
//methods for window management
|
||||
virtual uint32_t UnAckDataCount(); // Return count of number of unacked bytes
|
||||
virtual uint32_t BytesInFlight(); // Return total bytes in flight
|
||||
@@ -90,6 +92,7 @@ private:
|
||||
// Manage data tx/rx
|
||||
void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
|
||||
// XXX This should be virtual and overridden
|
||||
Ptr<TcpSocket> Copy ();
|
||||
void NewAck (SequenceNumber seq);
|
||||
// XXX This should be virtual and overridden
|
||||
void DupAck (const TcpHeader& t, uint32_t count);
|
||||
@@ -106,8 +109,8 @@ private:
|
||||
Ipv4EndPoint *m_endPoint;
|
||||
Ptr<Node> m_node;
|
||||
Ptr<TcpL4Protocol> m_tcp;
|
||||
Ipv4Address m_defaultAddress;
|
||||
uint16_t m_defaultPort;
|
||||
Ipv4Address m_remoteAddress;
|
||||
uint16_t m_remotePort;
|
||||
//these two are so that the socket/endpoint cloning works
|
||||
Ipv4Address m_localAddress;
|
||||
uint16_t m_localPort;
|
||||
|
||||
Reference in New Issue
Block a user