Finalizing interest limits. Now everything seem to work.
To work correctly, a lot of parameters have to be adjusted, including average
contentObject size, averageRTT, queues on nodes.
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 5d2ce7c..dc54f92 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -136,7 +136,10 @@
interestHeader.SetName (nameWithSequence);
interestHeader.SetInterestLifetime (m_interestLifeTime);
interestHeader.SetChildSelector (m_childSelector);
- interestHeader.SetExclude (Create<CcnxNameComponents> (m_exclude));
+ if (m_exclude.size ()>0)
+ {
+ interestHeader.SetExclude (Create<CcnxNameComponents> (m_exclude));
+ }
interestHeader.SetMaxSuffixComponents (m_maxSuffixComponents);
interestHeader.SetMinSuffixComponents (m_minSuffixComponents);
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index 0a82d0c..844acd4 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -50,7 +50,7 @@
MakeCcnxNameComponentsAccessor (&CcnxProducer::m_prefix),
MakeCcnxNameComponentsChecker ())
.AddAttribute ("PayloadSize", "Virtual payload size for Content packets",
- UintegerValue (100),
+ UintegerValue (1024),
MakeUintegerAccessor(&CcnxProducer::m_virtualPayloadSize),
MakeUintegerChecker<uint32_t>())
// .AddTraceSource ("InterestTrace", "Interests that were received",
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index c183413..d0c2882 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -63,8 +63,9 @@
main (int argc, char *argv[])
{
Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
- Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("1ms"));
+ Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("10ms"));
Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("1s"));
+ Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));
Packet::EnableChecking();
Packet::EnablePrinting();
@@ -88,8 +89,9 @@
// Install CCNx stack
NS_LOG_INFO ("Installing CCNx stack");
CcnxStackHelper ccnxHelper;
+ // ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
ccnxHelper.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
- ccnxHelper.EnableLimits (true);
+ ccnxHelper.EnableLimits (true, Seconds(0.1));
ccnxHelper.InstallAll ();
// Install IP stack (necessary to populate FIB)
@@ -118,7 +120,7 @@
// consumers.Start (Seconds (0.0));
// consumers.Stop (finishTime);
- CcnxProducerHelper producerHelper (prefix.str (),120);
+ CcnxProducerHelper producerHelper (prefix.str (),1024);
ApplicationContainer producers = producerHelper.Install (producer);
// producers.Start(Seconds(0.0));
diff --git a/examples/content-object-example.cc b/examples/content-object-example.cc
index fa9700e..8272e86 100644
--- a/examples/content-object-example.cc
+++ b/examples/content-object-example.cc
@@ -19,38 +19,38 @@
int
main (int argc, char *argv[])
{
- LogComponentEnable ("ContentObjectHeaderExample", LOG_ALL);
- LogComponentEnable ("Packet", LOG_ALL);
+ LogComponentEnable ("ContentObjectHeaderExample", LOG_ALL);
+ LogComponentEnable ("Packet", LOG_ALL);
- NS_LOG_INFO ("Test started");
+ NS_LOG_INFO ("Test started");
- Packet::EnablePrinting ();
- Packet::EnableChecking ();
- Packet packet (10);
+ Packet::EnablePrinting ();
+ Packet::EnableChecking ();
+ Packet packet (10);
- CcnxContentObjectHeader header;
- CcnxContentObjectTail trailer;
+ CcnxContentObjectHeader header;
+ CcnxContentObjectTail trailer;
- Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
- (*testname) ("1");
- header.SetName(testname);
+ Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
+ (*testname) ("1");
+ header.SetName(testname);
- NS_LOG_INFO ("Source: \n" << header << trailer);
+ NS_LOG_INFO ("Source: \n" << header << trailer);
- packet.AddHeader (header);
- packet.AddTrailer (trailer);
+ packet.AddHeader (header);
+ packet.AddTrailer (trailer);
- // NS_LOG_INFO ("Deserialized packet: \n" << packet);
+ // NS_LOG_INFO ("Deserialized packet: \n" << packet);
- NS_LOG_INFO ("Removing and deserializing individual headers");
+ NS_LOG_INFO ("Removing and deserializing individual headers");
- CcnxContentObjectHeader dst_header;
- CcnxContentObjectTail dst_trailer;
+ CcnxContentObjectHeader dst_header;
+ CcnxContentObjectTail dst_trailer;
- packet.RemoveHeader (dst_header);
- packet.RemoveTrailer (dst_trailer);
+ packet.RemoveHeader (dst_header);
+ packet.RemoveTrailer (dst_trailer);
- NS_LOG_INFO ("Target: \n" << dst_header << dst_trailer);
+ NS_LOG_INFO ("Target: \n" << dst_header << dst_trailer);
- return 0;
+ return 0;
}
diff --git a/examples/packet-sizes.cc b/examples/packet-sizes.cc
new file mode 100644
index 0000000..041cac6
--- /dev/null
+++ b/examples/packet-sizes.cc
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * 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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-header-helper.h"
+#include "ns3/header.h"
+#include "ns3/ccnx-name-components.h"
+#include "ns3/nstime.h"
+#include "ns3/string.h"
+#include "ns3/buffer.h"
+#include "ns3/packet.h"
+#include "ns3/log.h"
+
+using namespace ns3;
+#include <fstream>
+
+NS_LOG_COMPONENT_DEFINE ("PacketSizes");
+
+int
+main (int argc, char *argv[])
+{
+ NS_LOG_INFO ("Test started");
+
+ uint32_t size = 1024;
+ std::string namePrefixStr = "/1";
+ uint32_t start=0, end=100;
+
+ CommandLine cmd;
+ cmd.AddValue ("size", "ContentObject payload size", size);
+ cmd.AddValue ("name", "Prefix", namePrefixStr);
+ cmd.AddValue ("start", "Range start", start);
+ cmd.AddValue ("end", "Range end", end);
+ cmd.Parse (argc, argv);
+
+ CcnxNameComponents namePrefixValue;
+ std::istringstream is (namePrefixStr);
+ is >> namePrefixValue;
+
+ Packet::EnablePrinting ();
+ Packet::EnableChecking ();
+
+ double interestSize = 0.0;
+ double nackSize = 0.0;
+ double contentObjectSize = 0.0;
+
+ double progress = start;
+ double step = (end-start)/100.0;
+
+ progress += step;
+
+ NS_LOG_INFO (progress << ", " << step);
+
+ for (uint32_t currentSize = start; currentSize < end; currentSize++)
+ {
+ Ptr<CcnxNameComponents> namePrefix = Create<CcnxNameComponents> (namePrefixValue);
+ namePrefix->Add (currentSize);
+
+ NS_LOG_LOGIC (boost::cref (*namePrefix));
+
+ // Interest Packet (doesn't have a payload)
+ CcnxInterestHeader interestHeader;
+
+ interestHeader.SetName (namePrefix);
+ interestHeader.SetInterestLifetime (Seconds (4.0));
+ interestHeader.SetNonce (10101010);
+
+ Ptr<Packet> interestPacket = Create<Packet> (0);
+ interestPacket->AddHeader (interestHeader);
+
+ interestSize = interestSize + (1.0*interestPacket->GetSize () - interestSize) / (currentSize - start + 1);
+
+
+
+ // NACK
+ interestHeader.SetNack (CcnxInterestHeader::NACK_GIVEUP_PIT);
+
+ Ptr<Packet> nackPacket = Create<Packet> (0);
+ nackPacket->AddHeader (interestHeader);
+
+ nackSize = nackSize + (1.0*nackPacket->GetSize () - nackSize) / (currentSize - start + 1);
+
+ // ContentObject
+ CcnxContentObjectHeader coHeader;
+ CcnxContentObjectTail coTrailer;
+
+ coHeader.SetName (namePrefix);
+
+ Ptr<Packet> contentObject = Create<Packet> (size);
+
+ contentObject->AddHeader (coHeader);
+ contentObject->AddTrailer (coTrailer);
+
+ contentObjectSize = contentObjectSize + (1.0*contentObject->GetSize () - contentObjectSize ) / (currentSize - start + 1);
+
+ NS_LOG_DEBUG (interestSize << ", " << nackSize << ", " << contentObjectSize);
+
+ if (currentSize >= progress)
+ {
+ NS_LOG_INFO ("Current: " << currentSize << "/" << end);
+ progress += step;
+ }
+ }
+
+ NS_LOG_INFO ("Avg interest: " << interestSize << ", avg nack: " << nackSize << ", avg contentObject: " << contentObjectSize);
+
+ return 0;
+}
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 234a64c..d9f9d6b 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -141,9 +141,13 @@
}
void
-CcnxStackHelper::EnableLimits (bool enable/* = true*/)
+CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
{
+ NS_LOG_INFO ("EnableLimits: " << enable);
m_limitsEnabled = enable;
+ m_avgContentObjectSize = avgContentObject;
+ m_avgInterestSize = avgInterest;
+ m_avgRtt = avgRtt;
}
Ptr<CcnxFaceContainer>
@@ -198,9 +202,13 @@
if (m_limitsEnabled)
{
+ NS_LOG_INFO ("Limits are enabled");
Ptr<PointToPointNetDevice> p2p = DynamicCast<PointToPointNetDevice> (device);
if (p2p == 0)
- continue; // only PointToPointNetDevice supports limits
+ {
+ NS_LOG_INFO ("Non p2p interface");
+ continue; // only PointToPointNetDevice supports limits
+ }
// Setup bucket filtering
// Assume that we know average data packet size, and this size is equal default size
@@ -209,11 +217,13 @@
DataRateValue dataRate; device->GetAttribute ("DataRate", dataRate);
NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
- face->SetBucketMax
- (0.1 * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof (CcnxInterestHeader)));
-
- face->SetBucketLeak
- (0.97 * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof (CcnxInterestHeader)));
+
+ double maxInterestPackets = 1.0 * dataRate.Get ().GetBitRate () / 8.0 / m_avgContentObjectSize;
+ NS_LOG_INFO ("BucketMax: " << maxInterestPackets);
+
+ // Set bucket max to BDP
+ face->SetBucketMax (m_avgRtt.ToDouble (Time::S) * maxInterestPackets); // number of interests allowed
+ face->SetBucketLeak (maxInterestPackets);
}
face->SetUp ();
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index af45c2b..ee166fc 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -30,6 +30,7 @@
#include "ns3/ccnx-forwarding-helper.h"
#include "ns3/ccnx.h"
#include "ns3/ccnx-interest-header.h"
+#include "ns3/nstime.h"
namespace ns3 {
@@ -85,9 +86,14 @@
/**
* @brief Enable Interest limits (disabled by default)
+ *
+ * @param enable Enable or disable limits
+ * @param avgRtt Average RTT
+ * @param avgContentObject Average size of contentObject packets (including all headers)
+ * @param avgInterest Average size of interest packets (including all headers)
*/
void
- EnableLimits (bool enable = true);
+ EnableLimits (bool enable = true, Time avgRtt=Seconds(0.1), uint32_t avgContentObject=1100, uint32_t avgInterest=40);
/**
* \brief Install CCNx stack on the node
@@ -198,6 +204,9 @@
private:
ObjectFactory m_strategyFactory;
bool m_limitsEnabled;
+ Time m_avgRtt;
+ uint32_t m_avgContentObjectSize;
+ uint32_t m_avgInterestSize;
// /**
// * @brief Enable pcap output the indicated Ccnx and interface pair.
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index 51b3ba4..3c092e9 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -82,8 +82,12 @@
if (m_bucketMax > 0)
{
+ //NS_LOG_ERROR ("Limits enabled: " << m_bucketMax << ", current: " << m_bucket);
if (m_bucket+1.0 > m_bucketMax)
- return false;
+ {
+ //NS_LOG_ERROR ("Returning false");
+ return false;
+ }
m_bucket += 1.0;
}
@@ -95,11 +99,31 @@
CcnxFace::LeakBucket (const Time &interval)
{
const double leak = m_bucketLeak * interval.ToDouble (Time::S);
- m_bucket -= std::max (0.0, m_bucket - leak);
+ m_bucket = std::max (0.0, m_bucket - leak);
NS_LOG_ERROR ("max: " << m_bucketMax << ", Current bucket: " << m_bucket << ", leak size: " << leak << ", interval: " << interval << ", " << m_bucketLeak);
}
+void
+CcnxFace::SetBucketMax (double bucket)
+{
+ NS_LOG_FUNCTION (this << bucket);
+ m_bucketMax = bucket;
+}
+
+void
+CcnxFace::SetBucketLeak (double leak)
+{
+ NS_LOG_FUNCTION (this << leak);
+ m_bucketLeak = leak;
+}
+
+void
+CcnxFace::LeakBucketByOnePacket ()
+{
+ m_bucket = std::max (0.0, m_bucket-1.0);
+}
+
bool
CcnxFace::Send (Ptr<Packet> packet)
{
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 40de808..0499abb 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -165,13 +165,13 @@
*
* @param bucket maximum value for Interest allowance. If < 0, then limit will be disabled
*/
- inline void
+ void
SetBucketMax (double bucket);
/**
* @brief Set a normalized value (one second) for Interest allowance bucket leak
*/
- inline void
+ void
SetBucketLeak (double leak);
/**
@@ -182,7 +182,7 @@
void
LeakBucket (const Time &interval);
- inline void
+ void
LeakBucketByOnePacket ();
/**
@@ -248,24 +248,6 @@
return m_id;
}
-void
-CcnxFace::SetBucketMax (double bucket)
-{
- m_bucketMax = bucket;
-}
-
-void
-CcnxFace::SetBucketLeak (double leak)
-{
- m_bucketLeak = leak;
-}
-
-void
-CcnxFace::LeakBucketByOnePacket ()
-{
- m_bucket -= std::max (0.0, m_bucket-1.0);
-}
-
} // namespace ns3
#endif //CCNX_FACE_H
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 187a020..5484fb7 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -584,6 +584,8 @@
CcnxL3Protocol::LeakBuckets ()
{
NS_LOG_FUNCTION (this);
+ NS_LOG_ERROR ("Bucket Interval: " << m_bucketLeakInterval.ToDouble(Time::S));
+
BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces)
{
face->LeakBucket (m_bucketLeakInterval);
diff --git a/wscript b/wscript
index 77b33ad..914f9fb 100644
--- a/wscript
+++ b/wscript
@@ -80,6 +80,10 @@
obj = bld.create_ns3_program('interest-header-example', ['NDNabstraction'])
obj.source = 'examples/interest-header-example.cc'
+ obj = bld.create_ns3_program('packet-sizes', ['NDNabstraction'])
+ obj.source = 'examples/packet-sizes.cc'
+
+
# for path in ["examples"]:
# anode = bld.path.find_dir (path)
# if not anode or not anode.is_child_of(bld.srcnode):