From ebbea8ae40713eec7e67e480a8b164e7bb295e2a Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 12 Mar 2008 11:55:08 -0400 Subject: [PATCH] First cut at making the socket clone --- src/internet-node/tcp-l4-protocol.cc | 2 +- src/internet-node/tcp-socket.cc | 105 +++++++++++++++++++++++++-- src/internet-node/tcp-socket.h | 5 ++ 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/src/internet-node/tcp-l4-protocol.cc b/src/internet-node/tcp-l4-protocol.cc index 122ff264a..91d79c7b9 100644 --- a/src/internet-node/tcp-l4-protocol.cc +++ b/src/internet-node/tcp-l4-protocol.cc @@ -76,7 +76,7 @@ TcpStateMachine::TcpStateMachine() aT[LISTEN][APP_CLOSE] = SA (CLOSED, NO_ACT); aT[LISTEN][TIMEOUT] = SA (LISTEN, NO_ACT); aT[LISTEN][ACK_RX] = SA (LISTEN, NO_ACT); - aT[LISTEN][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX); //XXX hacked for now, should stay in listen and replicate + aT[LISTEN][SYN_RX] = SA (LISTEN, SYN_ACK_TX);//stay in listen and fork aT[LISTEN][SYN_ACK_RX] = SA (LISTEN, NO_ACT); aT[LISTEN][FIN_RX] = SA (LISTEN, NO_ACT); aT[LISTEN][FIN_ACK_RX] = SA (LISTEN, NO_ACT); diff --git a/src/internet-node/tcp-socket.cc b/src/internet-node/tcp-socket.cc index f2d8ad4cd..45d9532bc 100644 --- a/src/internet-node/tcp-socket.cc +++ b/src/internet-node/tcp-socket.cc @@ -77,6 +77,59 @@ TcpSocket::TcpSocket (Ptr node, Ptr tcp) NS_LOG_PARAMS (this<Copy(); + } + //copy the rtt if necessary + if (sock.m_rtt) + { + m_rtt = sock.m_rtt->Copy(); + } + //can't "copy" the endpoint just yes, must do this when we know the peer info + //too; this is in SYN_ACK_TX +} + TcpSocket::~TcpSocket () { NS_LOG_FUNCTION; @@ -134,6 +187,8 @@ TcpSocket::FinishBind (void) } m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, this)); m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, this)); + m_localAddress = m_endPoint->GetLocalAddress (); + m_localPort = m_endPoint->GetLocalPort (); return 0; } @@ -427,6 +482,9 @@ Actions_t TcpSocket::ProcessEvent (Events_t e) NS_LOG_LOGIC ("TcpSocket " << this << " moved from state " << saveState << " to state " <SetPeer (m_defaultAddress, m_defaultPort); NS_LOG_LOGIC ("TcpSocket " << this << " Connected!"); } + if (needCloseNotify && !m_closeNotified) { NS_LOG_LOGIC ("TcpSocket " << this << " transition to CLOSED from " @@ -513,6 +572,8 @@ bool TcpSocket::ProcessAction (Actions_t a) break; case SYN_ACK_TX: NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX"); + // TCP SYN Flag consumes one byte + ++m_nextRxSequence; SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); break; case FIN_TX: @@ -564,7 +625,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr p, const Address& fromAddress) { NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << p << "tcpHeader " << fromAddress); + NS_LOG_PARAMS (this << a << p << fromAddress); uint32_t localIfIndex; Ptr ipv4 = m_node->GetObject (); switch (a) @@ -572,12 +633,46 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr 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 (); - m_endPoint->SetPeer (m_defaultAddress, m_defaultPort); + m_defaultAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (); if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex)) + { + m_localAddress = ipv4->GetAddress (localIfIndex); + } + if (m_state == LISTEN) //this means we should fork a new TcpSocket { - m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex)); + //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 newSock = Create(*this); + 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); + } + + 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); diff --git a/src/internet-node/tcp-socket.h b/src/internet-node/tcp-socket.h index 3a7970fe8..691620c7e 100644 --- a/src/internet-node/tcp-socket.h +++ b/src/internet-node/tcp-socket.h @@ -46,6 +46,7 @@ public: * Create an unbound tcp socket. */ TcpSocket (Ptr node, Ptr tcp); + TcpSocket (const TcpSocket& sock); virtual ~TcpSocket (); virtual enum SocketErrno GetErrno (void) const; @@ -107,6 +108,10 @@ private: Ptr m_tcp; Ipv4Address m_defaultAddress; uint16_t m_defaultPort; + //these two are so that the socket/endpoint cloning works + Ipv4Address m_localAddress; + uint16_t m_localPort; + //XXX Dead code? Callback, uint32_t, const Address &> m_dummyRxCallback; Callback, uint8_t const*, uint32_t, const Address &> m_rxCallback;