Added TCP Hybla

This commit is contained in:
Natale Patriciello
2015-10-28 11:21:41 +01:00
parent 2903ebda5c
commit 653e2f9b05
3 changed files with 273 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 Natale Patriciello <natale.patriciello@gmail.com>
*
* 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<TcpNewReno> ()
.AddConstructor<TcpHybla> ()
.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<TcpSocketState> 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<TcpSocketState> 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<TcpSocketState> 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<TcpSocketState> 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<TcpCongestionOps>
TcpHybla::Fork (void)
{
return CopyObject<TcpHybla> (this);
}
std::string
TcpHybla::GetName () const
{
return "TcpHybla";
}
} // namespace ns3

View File

@@ -0,0 +1,90 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 Natale Patriciello <natale.patriciello@gmail.com>
*
* 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<TcpSocketState> tcb, uint32_t segmentsAcked,
const Time& rtt);
virtual std::string GetName () const;
virtual Ptr<TcpCongestionOps> Fork ();
protected:
virtual uint32_t SlowStart (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);
virtual void CongestionAvoidance (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);
private:
TracedValue<double> 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<TcpSocketState> tcb, const Time& rtt);
};
} // namespace ns3
#endif // TCPHYBLA_H

View File

@@ -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',