From 653e2f9b05a6c55c64b4a454b40d59684abc7cdf Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Wed, 28 Oct 2015 11:21:41 +0100 Subject: [PATCH] Added TCP Hybla --- src/internet/model/tcp-hybla.cc | 181 ++++++++++++++++++++++++++++++++ src/internet/model/tcp-hybla.h | 90 ++++++++++++++++ src/internet/wscript | 2 + 3 files changed, 273 insertions(+) create mode 100644 src/internet/model/tcp-hybla.cc create mode 100644 src/internet/model/tcp-hybla.h diff --git a/src/internet/model/tcp-hybla.cc b/src/internet/model/tcp-hybla.cc new file mode 100644 index 000000000..46f039ddd --- /dev/null +++ b/src/internet/model/tcp-hybla.cc @@ -0,0 +1,181 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 Natale Patriciello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "tcp-hybla.h" +#include "ns3/log.h" +#include "ns3/tcp-socket-base.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("TcpHybla"); +NS_OBJECT_ENSURE_REGISTERED (TcpHybla); + +TypeId +TcpHybla::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::TcpHybla") + .SetParent () + .AddConstructor () + .SetGroupName ("Internet") + .AddAttribute ("RRTT", "Reference RTT", + TimeValue (MilliSeconds (50)), + MakeTimeAccessor (&TcpHybla::m_rRtt), + MakeTimeChecker ()) + .AddTraceSource ("Rho", + "Rho parameter of Hybla", + MakeTraceSourceAccessor (&TcpHybla::m_rho), + "ns3::TracedValue::DoubleCallback") + ; + return tid; +} + +TcpHybla::TcpHybla () + : TcpNewReno (), + m_rho (1.0), + m_minRtt (Time::Max ()), + m_cWndCnt (0) +{ + NS_LOG_FUNCTION (this); +} + +TcpHybla::TcpHybla (const TcpHybla &sock) + : TcpNewReno (sock), + m_rho (sock.m_rho), + m_minRtt (sock.m_minRtt), + m_cWndCnt (sock.m_cWndCnt) +{ + NS_LOG_FUNCTION (this); +} + +TcpHybla::~TcpHybla () +{ + NS_LOG_FUNCTION (this); +} + +void +TcpHybla::RecalcParam (Ptr tcb, const Time &rtt) +{ + NS_LOG_FUNCTION (this << rtt); + + m_rho = std::max ((double) rtt.GetMilliSeconds () / m_rRtt.GetMilliSeconds (), 1.0); + + NS_ASSERT (m_rho > 0.0); + NS_LOG_DEBUG ("Calculated rho=" << m_rho); +} + +void +TcpHybla::PktsAcked (Ptr tcb, uint32_t segmentsAcked, + const Time &rtt) +{ + NS_LOG_FUNCTION (this << tcb << segmentsAcked << rtt); + + if (rtt < m_minRtt) + { + RecalcParam (tcb, rtt); + m_minRtt = rtt; + NS_LOG_DEBUG ("Updated m_minRtt=" << m_minRtt); + } +} + +uint32_t +TcpHybla::SlowStart (Ptr tcb, uint32_t segmentsAcked) +{ + NS_LOG_FUNCTION (this << tcb << segmentsAcked); + + NS_ASSERT (tcb->m_cWnd <= tcb->m_ssThresh); + + if (segmentsAcked >= 1) + { + /* + * slow start + * INC = 2^RHO - 1 + */ + + double increment = std::pow (2, m_rho) - 1.0; + NS_LOG_INFO ("Slow start: inc=" << increment); + + tcb->m_cWnd = std::min (tcb->m_cWnd + (increment * tcb->m_segmentSize), + tcb->m_ssThresh); + + NS_LOG_INFO ("In SlowStart, updated to cwnd " << tcb->m_cWnd << + " ssthresh " << tcb->m_ssThresh << + " with an increment of " << increment * tcb->m_segmentSize); + + return segmentsAcked - 1; + } + + return 0; +} + +void +TcpHybla::CongestionAvoidance (Ptr tcb, uint32_t segmentsAcked) +{ + NS_LOG_FUNCTION (this << tcb << segmentsAcked); + + uint32_t segCwnd; + double increment; + + while (segmentsAcked > 0) + { + /* + * congestion avoidance + * INC = RHO^2 / W + */ + segCwnd = tcb->GetCwndInSegments (); + increment = std::pow (m_rho, 2) / ((double) segCwnd); + + m_cWndCnt += increment; + segmentsAcked -= 1; + } + + if (m_cWndCnt >= 1.0) + { + // double to int truncates everytime. + uint32_t inc = (uint32_t) m_cWndCnt; + m_cWndCnt -= inc; + + NS_ASSERT (m_cWndCnt >= 0.0); + + /* This leaves space for a tcp pacing implementation; it would be easy + to setup a limit on the maximum increment of the cWnd per ACK received. + The remaining increment is leaved for the next ACK. */ + + tcb->m_cWnd += inc * tcb->m_segmentSize; + + + NS_LOG_INFO ("In CongAvoid, updated to cwnd " << tcb->m_cWnd << + " ssthresh " << tcb->m_ssThresh << + " with an increment of " << inc * tcb->m_segmentSize); + } +} + +Ptr +TcpHybla::Fork (void) +{ + return CopyObject (this); +} + +std::string +TcpHybla::GetName () const +{ + return "TcpHybla"; +} + + +} // namespace ns3 diff --git a/src/internet/model/tcp-hybla.h b/src/internet/model/tcp-hybla.h new file mode 100644 index 000000000..84cb0c1d5 --- /dev/null +++ b/src/internet/model/tcp-hybla.h @@ -0,0 +1,90 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 Natale Patriciello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef TCPHYBLA_H +#define TCPHYBLA_H + +#include "ns3/tcp-congestion-ops.h" +#include "ns3/traced-value.h" + +namespace ns3 { + +/** + * \brief Implementation of the TCP Hybla algorithm + * + * The key idea behind TCP Hybla is to obtain for long RTT connections the same + * instantaneous transmission rate of a reference TCP connection with lower RTT. + * With analytical steps, it is shown that this goal can be achieved by + * modifying the time scale, in order for the throughput to be independent from + * the RTT. This independence is obtained through the use of a coefficient rho. + * + * This coefficient is used to calculate both the slow start threshold + * and the congestion window when in slow start and in congestion avoidance, + * respectively. + * + * More information: http://dl.acm.org/citation.cfm?id=2756518 + */ +class TcpHybla : public TcpNewReno +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + /** + * Create an unbound tcp socket. + */ + TcpHybla (void); + + /** + * \brief Copy constructor + * \param sock the object to copy + */ + TcpHybla (const TcpHybla& sock); + + virtual ~TcpHybla (void); + + virtual void PktsAcked (Ptr tcb, uint32_t segmentsAcked, + const Time& rtt); + + virtual std::string GetName () const; + + virtual Ptr Fork (); + +protected: + virtual uint32_t SlowStart (Ptr tcb, uint32_t segmentsAcked); + virtual void CongestionAvoidance (Ptr tcb, uint32_t segmentsAcked); + +private: + TracedValue m_rho; //!< Rho parameter + Time m_minRtt; //!< Minimum smoothed round trip time value seen + Time m_rRtt; //!< Reference RTT + double m_cWndCnt; //!< cWnd integer-to-float counter + +private: + /** + * \brief Recalculate algorithm paramenters + */ + void RecalcParam (Ptr tcb, const Time& rtt); +}; + +} // namespace ns3 + +#endif // TCPHYBLA_H diff --git a/src/internet/wscript b/src/internet/wscript index 9285ea7b1..eb90993c8 100644 --- a/src/internet/wscript +++ b/src/internet/wscript @@ -146,6 +146,7 @@ def build(bld): 'model/icmpv6-l4-protocol.cc', 'model/tcp-socket-base.cc', 'model/tcp-highspeed.cc', + 'model/tcp-hybla.cc', 'model/tcp-congestion-ops.cc', 'model/tcp-westwood.cc', 'model/tcp-rx-buffer.cc', @@ -329,6 +330,7 @@ def build(bld): 'helper/ipv6-routing-helper.h', 'model/ipv6-address-generator.h', 'model/tcp-highspeed.h', + 'model/tcp-hybla.h', 'model/tcp-congestion-ops.h', 'model/tcp-westwood.h', 'model/tcp-socket-base.h',