diff --git a/src/internet-node/tcp-socket.cc b/src/internet-node/tcp-socket.cc index 2df2ba7d7..63b33bafb 100644 --- a/src/internet-node/tcp-socket.cc +++ b/src/internet-node/tcp-socket.cc @@ -79,7 +79,8 @@ TcpSocket::GetTypeId () m_pendingData (0), m_rtt (0), m_lastMeasuredRtt (Seconds(0.0)), - m_rxAvailable (0) + m_rxAvailable (0), //XXX zero? + m_maxTxBuffer (65536) //interpret 0 as no limit, //XXX hook into default values { NS_LOG_FUNCTION (this); @@ -124,7 +125,8 @@ TcpSocket::TcpSocket(const TcpSocket& sock) m_lastMeasuredRtt (Seconds(0.0)), m_cnTimeout (sock.m_cnTimeout), m_cnCount (sock.m_cnCount), - m_rxAvailable (0) + m_rxAvailable (0), + m_maxTxBuffer (0) //interpret 0 as no limit, //XXX hook into default values { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC("Invoked the copy constructor"); @@ -361,20 +363,19 @@ int TcpSocket::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) { // Ok to buffer some data to send + size = std::min(size, GetTxAvailable() ); //only buffer what can fit if (!m_pendingData) - { - m_pendingData = new PendingData (); // Create if non-existent - m_firstPendingSequence = m_nextTxSequence; // Note seq of first - } + { + m_pendingData = new PendingData (); // Create if non-existent + m_firstPendingSequence = m_nextTxSequence; // Note seq of first + } //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); - // We do not model any limit to the buffer, so report that the - // maximum is available - NotifySend (std::numeric_limits::max ()); + //NotifySend (GetTxAvailable ()); //XXX not here, do this when data acked if (!ProcessAction (action)) { return -1; // Failed, return zero @@ -439,8 +440,21 @@ TcpSocket::SendTo (const Address &address, Ptr p) uint32_t TcpSocket::GetTxAvailable (void) const { - // No finite send buffer is modelled - return 0xffffffff; + if (m_maxTxBuffer == 0) //interpret this as infinite buffer + { + return std::numeric_limits::max (); + } + if (m_pendingData != 0) + { + uint32_t unAckedDataSize = + m_pendingData->SizeFromSeq (m_firstPendingSequence, m_highestRxAck); + NS_ASSERT (m_maxTxBuffer >= unAckedDataSize); //else a logical error + return m_maxTxBuffer-unAckedDataSize; + } + else + { + return m_maxTxBuffer; + } } int @@ -757,9 +771,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr p, if (tcpHeader.GetAckNumber () > m_highestRxAck) { m_highestRxAck = tcpHeader.GetAckNumber (); - // We do not model any limit to the buffer, so report that the - // maximum is available - NotifySend (std::numeric_limits::max ()); + //NotifySend (GetTxAvailable() ); //XXX do when data gets acked } SendPendingData (); break; @@ -1158,9 +1170,9 @@ void TcpSocket::CommonNewAck (SequenceNumber ack, bool skipTimer) NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed m_highestRxAck = ack; // Note the highest recieved Ack - // We do not model any limit to the buffer, so report that the - // maximum is available - NotifySend (std::numeric_limits::max ()); + //m_highestRxAck advancing means some data was acked, and the size of free + //space in the buffer has increased + NotifySend (GetTxAvailable ()); if (ack > m_nextTxSequence) { m_nextTxSequence = ack; // If advanced diff --git a/src/internet-node/tcp-socket.h b/src/internet-node/tcp-socket.h index 2cf21c547..f68e19884 100644 --- a/src/internet-node/tcp-socket.h +++ b/src/internet-node/tcp-socket.h @@ -161,7 +161,9 @@ private: SequenceNumber m_nextRxSequence; //history data + //this is the incoming data buffer which sorts out of sequence data UnAckData_t m_bufferedData; + //this is kind of the tx buffer PendingData* m_pendingData; SequenceNumber m_firstPendingSequence; @@ -183,9 +185,12 @@ private: // Temporary queue for delivering data to application std::queue > m_deliveryQueue; - uint32_t m_rxAvailable; + uint32_t m_rxAvailable; + + // buffer limit for the outgoing queue + uint32_t m_maxTxBuffer; }; }//namespace ns3 -#endif /* UDP_SOCKET_H */ +#endif /* TCP_SOCKET_H */