Bug 385 - Add a generic "sequence number" class.
This commit is contained in:
195
src/common/sequence-number.cc
Normal file
195
src/common/sequence-number.cc
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2008-2010 INESC Porto
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
|
||||
//
|
||||
|
||||
#include "sequence-number.h"
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/traced-value.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class SequenceNumberTestObj : public Object
|
||||
{
|
||||
TracedValue<SequenceNumber32> m_testTracedSequenceNumber;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
SequenceNumberTestObj ()
|
||||
{
|
||||
m_testTracedSequenceNumber = SequenceNumber32 (0);
|
||||
}
|
||||
|
||||
static TypeId GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId("ns3::SequenceNumberTestObj")
|
||||
.SetParent<Object> ()
|
||||
.AddTraceSource ("TestTracedSequenceNumber",
|
||||
"A traceable sequence number",
|
||||
MakeTraceSourceAccessor (&SequenceNumberTestObj::m_testTracedSequenceNumber))
|
||||
.AddConstructor<SequenceNumberTestObj> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void IncSequenceNumber ()
|
||||
{
|
||||
m_testTracedSequenceNumber += 1;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class SequenceNumberTestCase : public TestCase
|
||||
{
|
||||
SequenceNumber32 m_oldval;
|
||||
SequenceNumber32 m_newval;
|
||||
|
||||
void SequenceNumberTracer (SequenceNumber32 oldval, SequenceNumber32 newval);
|
||||
|
||||
public:
|
||||
|
||||
SequenceNumberTestCase ();
|
||||
virtual ~SequenceNumberTestCase ();
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
SequenceNumberTestCase::SequenceNumberTestCase ()
|
||||
: TestCase ("SequenceNumber")
|
||||
{
|
||||
m_oldval = 0;
|
||||
m_newval = 0;
|
||||
}
|
||||
|
||||
SequenceNumberTestCase::~SequenceNumberTestCase ()
|
||||
{}
|
||||
|
||||
void
|
||||
SequenceNumberTestCase::SequenceNumberTracer (SequenceNumber32 oldval, SequenceNumber32 newval)
|
||||
{
|
||||
m_oldval = oldval;
|
||||
m_newval = newval;
|
||||
}
|
||||
|
||||
bool SequenceNumberTestCase::DoRun (void)
|
||||
{
|
||||
#define NS_TEST_ASSERT_EQUAL(a,b) NS_TEST_ASSERT_MSG_EQ(a,b, "foo")
|
||||
#define NS_TEST_ASSERT(a) NS_TEST_ASSERT_MSG_EQ(bool(a), true, "foo")
|
||||
|
||||
{
|
||||
SequenceNumber32 num1 (3), num2 (5);
|
||||
uint32_t value;
|
||||
|
||||
value = (num1 + num2).GetValue ();
|
||||
NS_TEST_ASSERT_EQUAL (value, 8);
|
||||
|
||||
num1 += num2.GetValue ();
|
||||
NS_TEST_ASSERT_EQUAL (num1, SequenceNumber32 (8));
|
||||
|
||||
++num1;
|
||||
NS_TEST_ASSERT_EQUAL (num1, SequenceNumber32 (9));
|
||||
|
||||
--num1;
|
||||
NS_TEST_ASSERT_EQUAL (num1, SequenceNumber32 (8));
|
||||
|
||||
num1++;
|
||||
NS_TEST_ASSERT_EQUAL (num1, SequenceNumber32 (9));
|
||||
|
||||
num1--;
|
||||
NS_TEST_ASSERT_EQUAL (num1, SequenceNumber32 (8));
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
SequenceNumber16 num1 (60900), num2 (5), num3 (10000);
|
||||
|
||||
NS_TEST_ASSERT (num1 == num1);
|
||||
|
||||
NS_TEST_ASSERT (num2 != num1);
|
||||
|
||||
NS_TEST_ASSERT (num3 > num2);
|
||||
NS_TEST_ASSERT (num3 >= num2);
|
||||
NS_TEST_ASSERT (num1 < num3);
|
||||
NS_TEST_ASSERT (num1 <= num3);
|
||||
|
||||
NS_TEST_ASSERT (num1 < num2);
|
||||
NS_TEST_ASSERT (num1 <= num2);
|
||||
NS_TEST_ASSERT (num2 > num1);
|
||||
NS_TEST_ASSERT (num2 >= num1);
|
||||
|
||||
NS_TEST_ASSERT (num1+num2 > num1);
|
||||
NS_TEST_ASSERT (num1+num2 >= num1);
|
||||
NS_TEST_ASSERT (num1 < num1+num2);
|
||||
NS_TEST_ASSERT (num1 <= num1+num2);
|
||||
|
||||
NS_TEST_ASSERT (num1 < num1+num3);
|
||||
NS_TEST_ASSERT (num1 <= num1+num3);
|
||||
NS_TEST_ASSERT (num1+num3 > num1);
|
||||
NS_TEST_ASSERT (num1+num3 >= num1);
|
||||
}
|
||||
|
||||
{
|
||||
NS_TEST_ASSERT_EQUAL ((SequenceNumber16 (1000) + SequenceNumber16 (6000)) - SequenceNumber16 (1000), 6000);
|
||||
NS_TEST_ASSERT_EQUAL ((SequenceNumber16 (60000) + SequenceNumber16 (6000)) - SequenceNumber16 (60000), 6000);
|
||||
NS_TEST_ASSERT_EQUAL (SequenceNumber16 (1000) - SequenceNumber16 (6000), -5000);
|
||||
NS_TEST_ASSERT_EQUAL ((SequenceNumber16 (60000) + SequenceNumber16 (1000)) - SequenceNumber16 (65000), -4000);
|
||||
}
|
||||
|
||||
{
|
||||
SequenceNumber32 num1 (3);
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (num1 + 10, SequenceNumber32 (13));
|
||||
num1 += -1;
|
||||
NS_TEST_ASSERT_EQUAL (num1, SequenceNumber32 (2));
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (num1 - (num1 - 100), 100);
|
||||
}
|
||||
|
||||
{
|
||||
Ptr<SequenceNumberTestObj> obj = CreateObject<SequenceNumberTestObj> ();
|
||||
obj->TraceConnectWithoutContext ("TestTracedSequenceNumber", MakeCallback (&SequenceNumberTestCase::SequenceNumberTracer, this));
|
||||
obj->IncSequenceNumber ();
|
||||
NS_TEST_ASSERT_EQUAL (m_oldval, SequenceNumber32 (0));
|
||||
NS_TEST_ASSERT_EQUAL (m_newval, SequenceNumber32 (1));
|
||||
obj->Dispose ();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static class SequenceNumberTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
SequenceNumberTestSuite ()
|
||||
: TestSuite ("SequenceNumber", UNIT)
|
||||
{
|
||||
AddTestCase (new SequenceNumberTestCase ());
|
||||
}
|
||||
} g_seqNumTests;
|
||||
|
||||
}
|
||||
|
||||
298
src/common/sequence-number.h
Normal file
298
src/common/sequence-number.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2008-2010 INESC Porto
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
|
||||
//
|
||||
|
||||
#ifndef __NS3_SEQ_NUM_H__
|
||||
#define __NS3_SEQ_NUM_H__
|
||||
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief Generic "sequence number" class
|
||||
*
|
||||
* This class can be used to handle sequence numbers. In networking
|
||||
* protocols, sequence numbers are fixed precision integer numbers
|
||||
* that are used to order events relative to each other. A sequence
|
||||
* number is expected to increase over time but, since it has a
|
||||
* limited number of bits, the number will "wrap around" from the
|
||||
* maximum value that can represented with the given number of bits
|
||||
* back to zero. For this reason, comparison of two sequence numbers,
|
||||
* and subtraction, is non-trivial. The SequenceNumber class behaves
|
||||
* like a number, with the usual arythmetic operators implemented, but
|
||||
* knows how to correctly compare and subtract sequence numbers.
|
||||
*
|
||||
* This is a templated class. To use it you need to supply two
|
||||
* fundamental types as template parameters: NUMERIC_TYPE and
|
||||
* SIGNED_TYPE. For instance, SequenceNumber<uint32_t, int32_t> gives
|
||||
* you a 32-bit sequence number, while SequenceNumber<uint16_t,
|
||||
* int16_t> is a 16-bit one. For your convenience, these are
|
||||
* typedef'ed as SequenceNumber32 and SequenceNumber16, respectively.
|
||||
*/
|
||||
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
|
||||
class SequenceNumber
|
||||
{
|
||||
public:
|
||||
SequenceNumber ()
|
||||
: m_value (0)
|
||||
{}
|
||||
|
||||
/**
|
||||
* \brief Constructs a SequenceNumber with the given value
|
||||
* \param value the sequence number value
|
||||
*/
|
||||
explicit SequenceNumber (NUMERIC_TYPE value)
|
||||
: m_value (value)
|
||||
{}
|
||||
|
||||
// copy contructor
|
||||
SequenceNumber (SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> const &value)
|
||||
: m_value (value.m_value)
|
||||
{}
|
||||
|
||||
// assignment from a plain number
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& operator= (NUMERIC_TYPE value)
|
||||
{
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// assignment from a sequence number
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& operator= (SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> const &value)
|
||||
{
|
||||
m_value = value.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// a SequenceNumber implicitly converts to a plain number, but not the other way around
|
||||
operator NUMERIC_TYPE () const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Extracts the numeric value of the sequence number
|
||||
* \returns the sequence number value
|
||||
*/
|
||||
NUMERIC_TYPE GetValue () const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
// prefix ++
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator++ ()
|
||||
{
|
||||
m_value++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// postfix ++
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator++ (int)
|
||||
{
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> retval (m_value);
|
||||
m_value++;
|
||||
return retval;
|
||||
}
|
||||
|
||||
// prefix --
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator-- ()
|
||||
{
|
||||
m_value--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// postfix --
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator-- (int)
|
||||
{
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> retval (m_value);
|
||||
m_value--;
|
||||
return retval;
|
||||
}
|
||||
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& operator+= (SIGNED_TYPE value)
|
||||
{
|
||||
m_value += value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& operator-= (SIGNED_TYPE value)
|
||||
{
|
||||
m_value -= value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator + (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
return SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> (m_value + other.m_value);
|
||||
}
|
||||
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator + (SIGNED_TYPE delta) const
|
||||
{
|
||||
return SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> (m_value + delta);
|
||||
}
|
||||
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator - (SIGNED_TYPE delta) const
|
||||
{
|
||||
return SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> (m_value - delta);
|
||||
}
|
||||
|
||||
SIGNED_TYPE operator - (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
static const NUMERIC_TYPE maxValue = std::numeric_limits<NUMERIC_TYPE>::max ();
|
||||
static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
|
||||
if (m_value > other.m_value)
|
||||
{
|
||||
NUMERIC_TYPE diff = m_value - other.m_value;
|
||||
if (diff < halfMaxValue)
|
||||
{
|
||||
return static_cast<SIGNED_TYPE> (diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
// |------------|------------|
|
||||
// ==== ===
|
||||
// ^ ^
|
||||
// other.m_value m_value
|
||||
return -(static_cast<SIGNED_TYPE> (maxValue - m_value + 1 + other.m_value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NUMERIC_TYPE diff = other.m_value - m_value;
|
||||
if (diff < halfMaxValue)
|
||||
{
|
||||
// |------------|------------|
|
||||
// ========
|
||||
// ^ ^
|
||||
// m_value other.m_value
|
||||
return -(static_cast<SIGNED_TYPE> (diff));
|
||||
}
|
||||
else
|
||||
{
|
||||
// |------------|------------|
|
||||
// ==== ===
|
||||
// ^ ^
|
||||
// m_value other.m_value
|
||||
return static_cast<SIGNED_TYPE> (maxValue - other.m_value + 1 + m_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Here is the critical part, how the comparison is made taking into
|
||||
// account wrap-around. From RFC 3626:
|
||||
//
|
||||
// The sequence number S1 is said to be "greater than" the sequence
|
||||
// number S2 if:
|
||||
//
|
||||
// S1 > S2 AND S1 - S2 <= MAXVALUE/2 OR
|
||||
//
|
||||
// S2 > S1 AND S2 - S1 > MAXVALUE/2
|
||||
bool operator > (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
|
||||
|
||||
return (((m_value > other.m_value) && (m_value - other.m_value) <= halfMaxValue)
|
||||
|| ((other.m_value > m_value) && (other.m_value - m_value) > halfMaxValue));
|
||||
}
|
||||
|
||||
bool operator == (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
return (m_value == other.m_value);
|
||||
}
|
||||
|
||||
bool operator != (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
return (m_value != other.m_value);
|
||||
}
|
||||
|
||||
bool operator <= (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
return (!this->operator> (other));
|
||||
}
|
||||
|
||||
bool operator >= (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
return (this->operator> (other) || this->operator== (other));
|
||||
}
|
||||
|
||||
bool operator < (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
|
||||
{
|
||||
return !this->operator> (other) && m_value != other.m_value;
|
||||
}
|
||||
|
||||
|
||||
template<typename NUMERIC_TYPE2, typename SIGNED_TYPE2>
|
||||
friend std::ostream & operator<< (std::ostream& os, const SequenceNumber<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
|
||||
|
||||
template<typename NUMERIC_TYPE2, typename SIGNED_TYPE2>
|
||||
friend std::istream & operator >> (std::istream &is, const SequenceNumber<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
|
||||
|
||||
private: // unimplemented operators
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& operator+= (SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> const &value);
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& operator-= (SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> const &value);
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator* (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator/ (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator% (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
bool operator ! () const;
|
||||
bool operator && (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
bool operator || (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator~ () const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator& (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator| (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator^ (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator<< (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator>> (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
|
||||
int operator* ();
|
||||
//SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>* operator& ();
|
||||
|
||||
private:
|
||||
NUMERIC_TYPE m_value;
|
||||
};
|
||||
|
||||
|
||||
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
|
||||
std::ostream &
|
||||
operator<< (std::ostream& os, const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &val)
|
||||
{
|
||||
os << val.m_value;
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
|
||||
std::istream & operator >> (std::istream &is, const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &val)
|
||||
{
|
||||
is >> val.m_value;
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
typedef SequenceNumber<uint32_t, int32_t> SequenceNumber32;
|
||||
typedef SequenceNumber<uint16_t, int16_t> SequenceNumber16;
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ def build(bld):
|
||||
'spectrum-type.cc',
|
||||
'spectrum-propagation-loss-model.cc',
|
||||
'friis-spectrum-propagation-loss.cc',
|
||||
'sequence-number.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
@@ -67,4 +68,5 @@ def build(bld):
|
||||
'spectrum-type.h',
|
||||
'spectrum-propagation-loss-model.h',
|
||||
'friis-spectrum-propagation-loss.h',
|
||||
'sequence-number.h',
|
||||
]
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
#include <list>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("MacRxMiddle");
|
||||
@@ -269,8 +270,7 @@ MacRxMiddle::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
||||
* So, this check cannot be used to discard old duplicate frames. It is
|
||||
* thus here only for documentation purposes.
|
||||
*/
|
||||
if (!SequenceControlSmaller (originator->GetLastSequenceControl (),
|
||||
hdr->GetSequenceControl ()))
|
||||
if (!(SequenceNumber16 (originator->GetLastSequenceControl ()) < SequenceNumber16 (hdr->GetSequenceControl ())))
|
||||
{
|
||||
NS_LOG_DEBUG ("Sequence numbers have looped back. last recorded="<<originator->GetLastSequenceControl ()<<
|
||||
" currently seen="<< hdr->GetSequenceControl ());
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "ns3/event-id.h"
|
||||
#include "tcp-typedefs.h"
|
||||
#include "pending-data.h"
|
||||
#include "sequence-number.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
|
||||
struct INetStreamSocket;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ void PendingData::Add (Ptr<Packet> p)
|
||||
size += p->GetSize();
|
||||
}
|
||||
|
||||
uint32_t PendingData::SizeFromSeq (const SequenceNumber& seqFront, const SequenceNumber& seqOffset)
|
||||
uint32_t PendingData::SizeFromSeq (const SequenceNumber32& seqFront, const SequenceNumber32& seqOffset)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << seqFront << seqOffset);
|
||||
uint32_t o1 = OffsetFromSeq (seqFront, seqOffset); // Offset to start of unused data
|
||||
@@ -134,7 +134,7 @@ uint32_t PendingData::SizeFromOffset (uint32_t offset)
|
||||
return size - offset; // Available data after offset
|
||||
}
|
||||
|
||||
uint32_t PendingData::OffsetFromSeq (const SequenceNumber& seqFront, const SequenceNumber& seqOffset)
|
||||
uint32_t PendingData::OffsetFromSeq (const SequenceNumber32& seqFront, const SequenceNumber32& seqOffset)
|
||||
{ // f is the first sequence number in this data, o is offset sequence
|
||||
NS_LOG_FUNCTION (this << seqFront << seqOffset);
|
||||
if (seqOffset < seqFront)
|
||||
@@ -215,14 +215,14 @@ Ptr<Packet> PendingData::CopyFromOffset (uint32_t s, uint32_t o)
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Packet> PendingData::CopyFromSeq (uint32_t s, const SequenceNumber& f, const SequenceNumber& o)
|
||||
Ptr<Packet> PendingData::CopyFromSeq (uint32_t s, const SequenceNumber32& f, const SequenceNumber32& o)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << s << f << o);
|
||||
return CopyFromOffset (s, OffsetFromSeq(f,o));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PendingData::RemoveToSeq (const SequenceNumber& seqFront, const SequenceNumber& seqOffset)
|
||||
PendingData::RemoveToSeq (const SequenceNumber32& seqFront, const SequenceNumber32& seqOffset)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << seqFront << seqOffset);
|
||||
uint32_t count = OffsetFromSeq (seqFront, seqOffset);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "ns3/packet.h"
|
||||
#include "pending-data.h"
|
||||
#include "sequence-number.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
namespace ns3
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
* \param seqFront sequence number of assumed first byte in the PendingData
|
||||
* \param seqOffset sequence number of offset
|
||||
*/
|
||||
virtual uint32_t SizeFromSeq (const SequenceNumber& seqFront, const SequenceNumber& seqOffset);
|
||||
virtual uint32_t SizeFromSeq (const SequenceNumber32& seqFront, const SequenceNumber32& seqOffset);
|
||||
// Inquire available data from offset
|
||||
/**
|
||||
* \return number of bytes in the data buffer beyond the offset specified
|
||||
@@ -88,10 +88,10 @@ public:
|
||||
* \param seqOffset higher sequence number
|
||||
* \return seqOffset-seqFront
|
||||
*/
|
||||
virtual uint32_t OffsetFromSeq (const SequenceNumber& seqFront, const SequenceNumber& seqOffset);
|
||||
virtual uint32_t OffsetFromSeq (const SequenceNumber32& seqFront, const SequenceNumber32& seqOffset);
|
||||
virtual Ptr<Packet> CopyFromOffset (uint32_t, uint32_t); // Size, offset, ret packet
|
||||
// Copy data, size, offset specified by sequence difference
|
||||
virtual Ptr<Packet> CopyFromSeq (uint32_t, const SequenceNumber&, const SequenceNumber&);
|
||||
virtual Ptr<Packet> CopyFromSeq (uint32_t, const SequenceNumber32&, const SequenceNumber32&);
|
||||
/**
|
||||
* Permits object to clear any pending data between seqFront and
|
||||
* seqOffset - 1). Callers should check the return value to determine
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
* \param seqOffset first sequence number in buffer that should be retained
|
||||
* \return number of bytes from the front that were removed from the buffer
|
||||
*/
|
||||
virtual uint32_t RemoveToSeq (const SequenceNumber& seqFront, const SequenceNumber& seqOffset);
|
||||
virtual uint32_t RemoveToSeq (const SequenceNumber32& seqFront, const SequenceNumber32& seqOffset);
|
||||
PendingData* Copy () const; // Create a copy of this header
|
||||
PendingData* CopyS (uint32_t); // Copy with new size
|
||||
PendingData* CopySD (uint32_t, uint8_t*); // Copy with new size, new data
|
||||
|
||||
@@ -61,7 +61,7 @@ RttEstimator::GetTypeId (void)
|
||||
}
|
||||
|
||||
//RttHistory methods
|
||||
RttHistory::RttHistory (SequenceNumber s, uint32_t c, Time t)
|
||||
RttHistory::RttHistory (SequenceNumber32 s, uint32_t c, Time t)
|
||||
: seq (s), count (c), time (t), retx (false)
|
||||
{
|
||||
}
|
||||
@@ -89,25 +89,25 @@ RttEstimator::~RttEstimator ()
|
||||
{
|
||||
}
|
||||
|
||||
void RttEstimator::SentSeq (SequenceNumber s, uint32_t c)
|
||||
void RttEstimator::SentSeq (SequenceNumber32 s, uint32_t c)
|
||||
{ // Note that a particular sequence has been sent
|
||||
if (s == next)
|
||||
{ // This is the next expected one, just log at end
|
||||
history.push_back (RttHistory (s, c, Simulator::Now () ));
|
||||
next = s + SequenceNumber (c); // Update next expected
|
||||
next = s + SequenceNumber32 (c); // Update next expected
|
||||
}
|
||||
else
|
||||
{ // This is a retransmit, find in list and mark as re-tx
|
||||
for (RttHistory_t::iterator i = history.begin (); i != history.end (); ++i)
|
||||
{
|
||||
if ((s >= i->seq) && (s < (i->seq + SequenceNumber (i->count))))
|
||||
if ((s >= i->seq) && (s < (i->seq + SequenceNumber32 (i->count))))
|
||||
{ // Found it
|
||||
i->retx = true;
|
||||
// One final test..be sure this re-tx does not extend "next"
|
||||
if ((s + SequenceNumber (c)) > next)
|
||||
if ((s + SequenceNumber32 (c)) > next)
|
||||
{
|
||||
next = s + SequenceNumber (c);
|
||||
i->count = ((s + SequenceNumber (c)) - i->seq); // And update count in hist
|
||||
next = s + SequenceNumber32 (c);
|
||||
i->count = ((s + SequenceNumber32 (c)) - i->seq); // And update count in hist
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -115,14 +115,14 @@ void RttEstimator::SentSeq (SequenceNumber s, uint32_t c)
|
||||
}
|
||||
}
|
||||
|
||||
Time RttEstimator::AckSeq (SequenceNumber a)
|
||||
Time RttEstimator::AckSeq (SequenceNumber32 a)
|
||||
{ // An ack has been received, calculate rtt and log this measurement
|
||||
// Note we use a linear search (O(n)) for this since for the common
|
||||
// case the ack'ed packet will be at the head of the list
|
||||
Time m = Seconds (0.0);
|
||||
if (history.size () == 0) return (m); // No pending history, just exit
|
||||
RttHistory& h = history.front ();
|
||||
if (!h.retx && a >= (h.seq + SequenceNumber (h.count)))
|
||||
if (!h.retx && a >= (h.seq + SequenceNumber32 (h.count)))
|
||||
{ // Ok to use this sample
|
||||
m = Simulator::Now () - h.time; // Elapsed time
|
||||
Measurement(m); // Log the measurement
|
||||
@@ -132,7 +132,7 @@ Time RttEstimator::AckSeq (SequenceNumber a)
|
||||
while(history.size() > 0)
|
||||
{
|
||||
RttHistory& h = history.front ();
|
||||
if ((h.seq + SequenceNumber(h.count)) > a) break; // Done removing
|
||||
if ((h.seq + SequenceNumber32(h.count)) > a) break; // Done removing
|
||||
history.pop_front (); // Remove
|
||||
}
|
||||
return m;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define __rtt_estimator_h__
|
||||
|
||||
#include <deque>
|
||||
#include "sequence-number.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/object.h"
|
||||
|
||||
@@ -39,10 +39,10 @@ namespace ns3 {
|
||||
*/
|
||||
class RttHistory {
|
||||
public:
|
||||
RttHistory (SequenceNumber s, uint32_t c, Time t);
|
||||
RttHistory (SequenceNumber32 s, uint32_t c, Time t);
|
||||
RttHistory (const RttHistory& h); // Copy constructor
|
||||
public:
|
||||
SequenceNumber seq; // First sequence number in packet sent
|
||||
SequenceNumber32 seq; // First sequence number in packet sent
|
||||
uint32_t count; // Number of bytes sent
|
||||
Time time; // Time this one was sent
|
||||
bool retx; // True if this has been retransmitted
|
||||
@@ -58,20 +58,20 @@ public:
|
||||
RttEstimator(const RttEstimator&); // Copy constructor
|
||||
virtual ~RttEstimator();
|
||||
|
||||
virtual void SentSeq(SequenceNumber, uint32_t);
|
||||
virtual Time AckSeq(SequenceNumber);
|
||||
virtual void SentSeq(SequenceNumber32, uint32_t);
|
||||
virtual Time AckSeq(SequenceNumber32);
|
||||
virtual void ClearSent();
|
||||
virtual void Measurement(Time t) = 0;
|
||||
virtual Time Estimate() = 0;
|
||||
virtual Time RetransmitTimeout() = 0;
|
||||
void Init(SequenceNumber s) { next = s;}
|
||||
void Init(SequenceNumber32 s) { next = s;}
|
||||
virtual Ptr<RttEstimator> Copy() const = 0;
|
||||
virtual void IncreaseMultiplier();
|
||||
virtual void ResetMultiplier();
|
||||
virtual void Reset();
|
||||
|
||||
private:
|
||||
SequenceNumber next; // Next expected sequence to be sent
|
||||
SequenceNumber32 next; // Next expected sequence to be sent
|
||||
RttHistory_t history; // List of sent packet
|
||||
double m_maxMultiplier;
|
||||
public:
|
||||
|
||||
@@ -59,11 +59,11 @@ void TcpHeader::SetDestinationPort (uint16_t port)
|
||||
{
|
||||
m_destinationPort = port;
|
||||
}
|
||||
void TcpHeader::SetSequenceNumber (SequenceNumber sequenceNumber)
|
||||
void TcpHeader::SetSequenceNumber (SequenceNumber32 sequenceNumber)
|
||||
{
|
||||
m_sequenceNumber = sequenceNumber;
|
||||
}
|
||||
void TcpHeader::SetAckNumber (SequenceNumber ackNumber)
|
||||
void TcpHeader::SetAckNumber (SequenceNumber32 ackNumber)
|
||||
{
|
||||
m_ackNumber = ackNumber;
|
||||
}
|
||||
@@ -92,11 +92,11 @@ uint16_t TcpHeader::GetDestinationPort () const
|
||||
{
|
||||
return m_destinationPort;
|
||||
}
|
||||
SequenceNumber TcpHeader::GetSequenceNumber () const
|
||||
SequenceNumber32 TcpHeader::GetSequenceNumber () const
|
||||
{
|
||||
return m_sequenceNumber;
|
||||
}
|
||||
SequenceNumber TcpHeader::GetAckNumber () const
|
||||
SequenceNumber32 TcpHeader::GetAckNumber () const
|
||||
{
|
||||
return m_ackNumber;
|
||||
}
|
||||
@@ -209,8 +209,8 @@ void TcpHeader::Serialize (Buffer::Iterator start) const
|
||||
Buffer::Iterator i = start;
|
||||
i.WriteHtonU16 (m_sourcePort);
|
||||
i.WriteHtonU16 (m_destinationPort);
|
||||
i.WriteHtonU32 (m_sequenceNumber);
|
||||
i.WriteHtonU32 (m_ackNumber);
|
||||
i.WriteHtonU32 (m_sequenceNumber.GetValue ());
|
||||
i.WriteHtonU32 (m_ackNumber.GetValue ());
|
||||
i.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
|
||||
i.WriteHtonU16 (m_windowSize);
|
||||
i.WriteHtonU16 (0);
|
||||
|
||||
@@ -61,11 +61,11 @@ public:
|
||||
/**
|
||||
* \param sequenceNumber the sequence number for this TcpHeader
|
||||
*/
|
||||
void SetSequenceNumber (SequenceNumber sequenceNumber);
|
||||
void SetSequenceNumber (SequenceNumber32 sequenceNumber);
|
||||
/**
|
||||
* \param ackNumber the ACK number for this TcpHeader
|
||||
*/
|
||||
void SetAckNumber (SequenceNumber ackNumber);
|
||||
void SetAckNumber (SequenceNumber32 ackNumber);
|
||||
/**
|
||||
* \param length the length of this TcpHeader
|
||||
*/
|
||||
@@ -96,11 +96,11 @@ public:
|
||||
/**
|
||||
* \return the sequence number for this TcpHeader
|
||||
*/
|
||||
SequenceNumber GetSequenceNumber () const;
|
||||
SequenceNumber32 GetSequenceNumber () const;
|
||||
/**
|
||||
* \return the ACK number for this TcpHeader
|
||||
*/
|
||||
SequenceNumber GetAckNumber () const;
|
||||
SequenceNumber32 GetAckNumber () const;
|
||||
/**
|
||||
* \return the length of this TcpHeader
|
||||
*/
|
||||
@@ -153,8 +153,8 @@ private:
|
||||
uint16_t CalculateHeaderChecksum (uint16_t size) const;
|
||||
uint16_t m_sourcePort;
|
||||
uint16_t m_destinationPort;
|
||||
uint32_t m_sequenceNumber;
|
||||
uint32_t m_ackNumber;
|
||||
SequenceNumber32 m_sequenceNumber;
|
||||
SequenceNumber32 m_ackNumber;
|
||||
uint8_t m_length; // really a uint4_t
|
||||
uint8_t m_flags; // really a uint6_t
|
||||
uint16_t m_windowSize;
|
||||
|
||||
@@ -534,8 +534,8 @@ TcpL4Protocol::Receive (Ptr<Packet> packet,
|
||||
else
|
||||
{
|
||||
header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
|
||||
header.SetSequenceNumber (SequenceNumber (0));
|
||||
header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber (1));
|
||||
header.SetSequenceNumber (SequenceNumber32 (0));
|
||||
header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
|
||||
}
|
||||
header.SetSourcePort (tcpHeader.GetDestinationPort ());
|
||||
header.SetDestinationPort (tcpHeader.GetSourcePort ());
|
||||
@@ -571,7 +571,7 @@ TcpL4Protocol::Send (Ptr<Packet> packet,
|
||||
daddr,
|
||||
PROT_NUMBER);
|
||||
tcpHeader.SetFlags (TcpHeader::ACK);
|
||||
tcpHeader.SetAckNumber (0);
|
||||
tcpHeader.SetAckNumber (SequenceNumber32 (0));
|
||||
|
||||
packet->AddHeader (tcpHeader);
|
||||
|
||||
|
||||
@@ -347,7 +347,7 @@ TcpSocketImpl::Close (void)
|
||||
" deferring close, state " << m_state);
|
||||
return 0;
|
||||
}
|
||||
m_finSequence = m_nextTxSequence + SequenceNumber (1);
|
||||
m_finSequence = m_nextTxSequence + SequenceNumber32 (1);
|
||||
Actions_t action = ProcessEvent (APP_CLOSE);
|
||||
ProcessAction (action);
|
||||
return 0;
|
||||
@@ -548,7 +548,7 @@ TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
|
||||
<< m_bufferedData.size ()
|
||||
<< " time " << Simulator::Now ());
|
||||
i = m_bufferedData.begin ();
|
||||
SequenceNumber s1 = 0;
|
||||
SequenceNumber32 s1 (0);
|
||||
if (i->first > m_nextRxSequence)
|
||||
{
|
||||
break; // we're done, no more in-sequence data exits
|
||||
@@ -588,7 +588,7 @@ TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
|
||||
uint32_t avail = maxSize - outPacket->GetSize();
|
||||
outPacket->AddAtEnd(i->second->CreateFragment(0,avail));
|
||||
//put the rest back into the buffer
|
||||
m_bufferedData[i->first+SequenceNumber(avail)]
|
||||
m_bufferedData[i->first+SequenceNumber32(avail)]
|
||||
= i->second->CreateFragment(avail,i->second->GetSize()-avail);
|
||||
m_rxAvailable += i->second->GetSize()-avail;
|
||||
m_rxBufSize += i->second->GetSize()-avail;
|
||||
@@ -971,7 +971,7 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
// This is the cloned endpoint
|
||||
// TCP SYN consumes one byte
|
||||
m_nextRxSequence = tcpHeader.GetSequenceNumber ()
|
||||
+ SequenceNumber (1);
|
||||
+ SequenceNumber32 (1);
|
||||
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
|
||||
}
|
||||
|
||||
@@ -979,7 +979,7 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
case ACK_TX_1:
|
||||
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX_1");
|
||||
// TCP SYN consumes one byte
|
||||
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
|
||||
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber32(1);
|
||||
m_nextTxSequence = tcpHeader.GetAckNumber ();
|
||||
m_firstPendingSequence = m_nextTxSequence; //bug 166
|
||||
NS_LOG_DEBUG ("TcpSocketImpl " << this << " ACK_TX_1" <<
|
||||
@@ -1045,7 +1045,7 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
||||
if (m_finSequence != m_nextRxSequence)
|
||||
{
|
||||
// process close later
|
||||
m_finSequence = tcpHeader.GetSequenceNumber () + SequenceNumber (p->GetSize ());
|
||||
m_finSequence = tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ());
|
||||
m_pendingClose = true;
|
||||
NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose"
|
||||
<< " rxseq " << tcpHeader.GetSequenceNumber ()
|
||||
@@ -1168,10 +1168,10 @@ bool TcpSocketImpl::SendPendingData (bool withAck)
|
||||
uint32_t sz = p->GetSize (); // Size of packet
|
||||
uint32_t remainingData = m_pendingData->SizeFromSeq(
|
||||
m_firstPendingSequence,
|
||||
m_nextTxSequence + SequenceNumber (sz));
|
||||
m_nextTxSequence + SequenceNumber32 (sz));
|
||||
if (m_closeOnEmpty && (remainingData == 0))
|
||||
{
|
||||
m_finSequence = m_nextTxSequence + SequenceNumber (1 + sz);
|
||||
m_finSequence = m_nextTxSequence + SequenceNumber32 (1 + sz);
|
||||
flags = TcpHeader::FIN;
|
||||
m_state = FIN_WAIT_1;
|
||||
}
|
||||
@@ -1303,8 +1303,8 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
|
||||
UnAckData_t::iterator next = m_bufferedData.upper_bound (m_nextRxSequence);
|
||||
if (next != m_bufferedData.end ())
|
||||
{
|
||||
SequenceNumber nextBufferedSeq = next->first;
|
||||
if (m_nextRxSequence + SequenceNumber(s) > nextBufferedSeq)
|
||||
SequenceNumber32 nextBufferedSeq = next->first;
|
||||
if (m_nextRxSequence + SequenceNumber32(s) > nextBufferedSeq)
|
||||
{//tail end isn't all new, trim enough off the end
|
||||
s = nextBufferedSeq - m_nextRxSequence;
|
||||
}
|
||||
@@ -1344,14 +1344,14 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
|
||||
NS_LOG_LOGIC ("Case 2, buffering " << tcpHeader.GetSequenceNumber () );
|
||||
UnAckData_t::iterator previous =
|
||||
m_bufferedData.lower_bound (tcpHeader.GetSequenceNumber ());
|
||||
SequenceNumber startSeq = tcpHeader.GetSequenceNumber();
|
||||
SequenceNumber32 startSeq = tcpHeader.GetSequenceNumber();
|
||||
if (previous != m_bufferedData.begin ())
|
||||
{
|
||||
--previous;
|
||||
startSeq = previous->first + SequenceNumber(previous->second->GetSize());
|
||||
startSeq = previous->first + SequenceNumber32(previous->second->GetSize());
|
||||
if (startSeq > tcpHeader.GetSequenceNumber ())
|
||||
{
|
||||
s = tcpHeader.GetSequenceNumber () + SequenceNumber(s) - startSeq;
|
||||
s = tcpHeader.GetSequenceNumber () + SequenceNumber32(s) - startSeq;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1362,8 +1362,8 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
|
||||
UnAckData_t::iterator next = m_bufferedData.upper_bound (tcpHeader.GetSequenceNumber());
|
||||
if (next != m_bufferedData.end ())
|
||||
{
|
||||
SequenceNumber nextBufferedSeq = next->first;
|
||||
if (startSeq + SequenceNumber(s) > nextBufferedSeq)
|
||||
SequenceNumber32 nextBufferedSeq = next->first;
|
||||
if (startSeq + SequenceNumber32(s) > nextBufferedSeq)
|
||||
{//tail end isn't all new either, trim enough off the end
|
||||
s = nextBufferedSeq - startSeq;
|
||||
}
|
||||
@@ -1390,25 +1390,25 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
|
||||
++next;
|
||||
if(next != m_bufferedData.end())
|
||||
{
|
||||
NS_ASSERT(next->first >= i->first + SequenceNumber(i->second->GetSize ()));
|
||||
NS_ASSERT(next->first >= i->first + SequenceNumber32(i->second->GetSize ()));
|
||||
}
|
||||
}
|
||||
else if (tcpHeader.GetSequenceNumber () + SequenceNumber(s) > m_nextRxSequence)
|
||||
else if (tcpHeader.GetSequenceNumber () + SequenceNumber32(s) > m_nextRxSequence)
|
||||
{//parial new data case, only part of the packet is new data
|
||||
//trim the beginning
|
||||
s = tcpHeader.GetSequenceNumber () + SequenceNumber(s) - m_nextRxSequence; //how much new
|
||||
s = tcpHeader.GetSequenceNumber () + SequenceNumber32(s) - m_nextRxSequence; //how much new
|
||||
//possibly trim off the end
|
||||
UnAckData_t::iterator next = m_bufferedData.upper_bound (m_nextRxSequence);
|
||||
if (next != m_bufferedData.end ())
|
||||
{
|
||||
SequenceNumber nextBufferedSeq = next->first;
|
||||
if (m_nextRxSequence + SequenceNumber(s) > nextBufferedSeq)
|
||||
SequenceNumber32 nextBufferedSeq = next->first;
|
||||
if (m_nextRxSequence + SequenceNumber32(s) > nextBufferedSeq)
|
||||
{//tail end isn't all new either, trim enough off the end
|
||||
s = nextBufferedSeq - m_nextRxSequence;
|
||||
}
|
||||
}
|
||||
p = p->CreateFragment (m_nextRxSequence - tcpHeader.GetSequenceNumber (),s);
|
||||
SequenceNumber start = m_nextRxSequence;
|
||||
SequenceNumber32 start = m_nextRxSequence;
|
||||
m_nextRxSequence += s; // Advance next expected sequence
|
||||
//buffer the new fragment, it'll be read by call to Recv
|
||||
UnAckData_t::iterator i = m_bufferedData.find (start);
|
||||
@@ -1449,7 +1449,7 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
|
||||
}
|
||||
}
|
||||
|
||||
void TcpSocketImpl::RxBufFinishInsert (SequenceNumber seq)
|
||||
void TcpSocketImpl::RxBufFinishInsert (SequenceNumber32 seq)
|
||||
{
|
||||
//putting data into the buffer might have filled in a sequence gap so we have
|
||||
//to iterate through the list to find the largest contiguous sequenced chunk,
|
||||
@@ -1460,11 +1460,11 @@ void TcpSocketImpl::RxBufFinishInsert (SequenceNumber seq)
|
||||
//make sure the buffer is logically sequenced
|
||||
if(next != m_bufferedData.end())
|
||||
{
|
||||
NS_ASSERT(next->first >= i->first + SequenceNumber(i->second->GetSize ()));
|
||||
NS_ASSERT(next->first >= i->first + SequenceNumber32(i->second->GetSize ()));
|
||||
}
|
||||
while(next != m_bufferedData.end())
|
||||
{
|
||||
if(i->first + SequenceNumber(i->second->GetSize ()) == next->first)
|
||||
if(i->first + SequenceNumber32(i->second->GetSize ()) == next->first)
|
||||
{
|
||||
//next packet is in sequence, count it
|
||||
m_rxAvailable += next->second->GetSize();
|
||||
@@ -1485,7 +1485,7 @@ void TcpSocketImpl::DelAckTimeout ()
|
||||
SendEmptyPacket (TcpHeader::ACK);
|
||||
}
|
||||
|
||||
void TcpSocketImpl::CommonNewAck (SequenceNumber ack, bool skipTimer)
|
||||
void TcpSocketImpl::CommonNewAck (SequenceNumber32 ack, bool skipTimer)
|
||||
{ // CommonNewAck is called only for "New" (non-duplicate) acks
|
||||
// and MUST be called by any subclass, from the NewAck function
|
||||
// Always cancel any pending re-tx timer on new acknowledgement
|
||||
@@ -1566,7 +1566,7 @@ Ptr<TcpSocketImpl> TcpSocketImpl::Copy ()
|
||||
return CopyObject<TcpSocketImpl> (this);
|
||||
}
|
||||
|
||||
void TcpSocketImpl::NewAck (SequenceNumber seq)
|
||||
void TcpSocketImpl::NewAck (SequenceNumber32 seq)
|
||||
{ // New acknowledgement up to sequence number "seq"
|
||||
// Adjust congestion window in response to new ack's received
|
||||
NS_LOG_FUNCTION (this << seq);
|
||||
@@ -1704,7 +1704,7 @@ void TcpSocketImpl::Retransmit ()
|
||||
// Calculate remaining data for COE check
|
||||
uint32_t remainingData = m_pendingData->SizeFromSeq (
|
||||
m_firstPendingSequence,
|
||||
m_nextTxSequence + SequenceNumber(p->GetSize ()));
|
||||
m_nextTxSequence + SequenceNumber32(p->GetSize ()));
|
||||
if (m_closeOnEmpty && remainingData == 0)
|
||||
{ // Add the FIN flag
|
||||
flags = flags | TcpHeader::FIN;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "ns3/event-id.h"
|
||||
#include "tcp-typedefs.h"
|
||||
#include "pending-data.h"
|
||||
#include "sequence-number.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
#include "rtt-estimator.h"
|
||||
|
||||
|
||||
@@ -133,16 +133,16 @@ private:
|
||||
|
||||
// Manage data tx/rx
|
||||
void NewRx (Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAddress);
|
||||
void RxBufFinishInsert (SequenceNumber);
|
||||
void RxBufFinishInsert (SequenceNumber32);
|
||||
Ptr<TcpSocketImpl> Copy ();
|
||||
virtual void NewAck (SequenceNumber seq);
|
||||
virtual void NewAck (SequenceNumber32 seq);
|
||||
virtual void DupAck (const TcpHeader& t, uint32_t count);
|
||||
virtual void ReTxTimeout ();
|
||||
void DelAckTimeout ();
|
||||
void LastAckTimeout ();
|
||||
void PersistTimeout ();
|
||||
void Retransmit ();
|
||||
void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
|
||||
void CommonNewAck (SequenceNumber32 seq, bool skipTimer = false);
|
||||
// All timers are cancelled when the endpoint is deleted, to insure
|
||||
// we don't have additional activity
|
||||
void CancelAllTimers();
|
||||
@@ -194,16 +194,16 @@ private:
|
||||
|
||||
|
||||
//sequence info, sender side
|
||||
SequenceNumber m_nextTxSequence;
|
||||
SequenceNumber m_highTxMark;
|
||||
SequenceNumber m_highestRxAck;
|
||||
SequenceNumber m_lastRxAck;
|
||||
SequenceNumber32 m_nextTxSequence;
|
||||
SequenceNumber32 m_highTxMark;
|
||||
SequenceNumber32 m_highestRxAck;
|
||||
SequenceNumber32 m_lastRxAck;
|
||||
|
||||
//sequence info, receiver side
|
||||
SequenceNumber m_nextRxSequence; //next expected sequence
|
||||
SequenceNumber32 m_nextRxSequence; //next expected sequence
|
||||
|
||||
//sequence number where fin was sent or received
|
||||
SequenceNumber m_finSequence;
|
||||
SequenceNumber32 m_finSequence;
|
||||
|
||||
//Rx buffer
|
||||
UnAckData_t m_bufferedData; //buffer which sorts out of sequence data
|
||||
@@ -216,7 +216,7 @@ private:
|
||||
|
||||
//this is kind of the tx buffer
|
||||
PendingData* m_pendingData;
|
||||
SequenceNumber m_firstPendingSequence;
|
||||
SequenceNumber32 m_firstPendingSequence;
|
||||
|
||||
// Window management
|
||||
uint32_t m_segmentSize; //SegmentSize
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "sequence-number.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
|
||||
#ifndef TCP_TYPEDEFS_H
|
||||
#define TCP_TYPEDEFS_H
|
||||
@@ -95,7 +95,7 @@ typedef std::vector<StateActionVec_t> StateActions_t; // One per current state
|
||||
typedef std::vector<Events_t> EventVec_t; // For flag events lookup
|
||||
|
||||
//type for managing buffered out of sequence data
|
||||
typedef std::map<SequenceNumber, Ptr<Packet> > UnAckData_t;
|
||||
typedef std::map<SequenceNumber32, Ptr<Packet> > UnAckData_t;
|
||||
|
||||
class TcpStateMachine {
|
||||
public:
|
||||
|
||||
@@ -93,7 +93,6 @@ def build(bld):
|
||||
'udp-socket-factory-impl.cc',
|
||||
'tcp-socket-factory-impl.cc',
|
||||
'pending-data.cc',
|
||||
'sequence-number.cc',
|
||||
'rtt-estimator.cc',
|
||||
'ipv4-raw-socket-factory-impl.cc',
|
||||
'ipv4-raw-socket-impl.cc',
|
||||
@@ -126,7 +125,6 @@ def build(bld):
|
||||
headers.source = [
|
||||
'udp-header.h',
|
||||
'tcp-header.h',
|
||||
'sequence-number.h',
|
||||
'icmpv4.h',
|
||||
'icmpv6-header.h',
|
||||
# used by routing
|
||||
|
||||
Reference in New Issue
Block a user