Added TCP Hybla
This commit is contained in:
181
src/internet/model/tcp-hybla.cc
Normal file
181
src/internet/model/tcp-hybla.cc
Normal 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
|
||||
90
src/internet/model/tcp-hybla.h
Normal file
90
src/internet/model/tcp-hybla.h
Normal 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
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user