stable version 1.0
This commit is contained in:
1 parent
4613da0c4a
commit
d75b3d40d9
23 files changed
+4122
-25320
No files matched your search
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "gnu++14",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"compileCommands": "${workspaceFolder}/ns-3/build/compile_commands.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"limits": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"strstream": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"*.ipp": "cpp"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Disabled"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Waf: Entering directory `/home/dutacm/MIRCC/MIRCC05/ns-3/build'
|
||||
@@ -155,6 +155,28 @@ GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lp
|
||||
lpPacket.add<lp::PitTokenField>(*pitToken);
|
||||
}
|
||||
|
||||
//add by ljq
|
||||
auto PTag = netPkt.getTag<lp::PTag>();
|
||||
if (PTag != nullptr) {
|
||||
lpPacket.add<lp::PTagField>(*PTag);
|
||||
}
|
||||
|
||||
auto PathidTag = netPkt.getTag<lp::PathidTag>();
|
||||
if (PathidTag != nullptr) {
|
||||
lpPacket.add<lp::PathidTagField>(*PathidTag);
|
||||
}
|
||||
|
||||
auto RpTag = netPkt.getTag<lp::RpTag>();
|
||||
if (RpTag != nullptr) {
|
||||
lpPacket.add<lp::RpTagField>(*RpTag);
|
||||
}
|
||||
|
||||
auto RsTag = netPkt.getTag<lp::RsTag>();
|
||||
if (RsTag != nullptr) {
|
||||
lpPacket.add<lp::RsTagField>(*RsTag);
|
||||
}
|
||||
//
|
||||
|
||||
shared_ptr<lp::HopCountTag> hopCountTag = netPkt.getTag<lp::HopCountTag>();
|
||||
if (hopCountTag != nullptr) {
|
||||
lpPacket.add<lp::HopCountTagField>(*hopCountTag);
|
||||
@@ -364,6 +386,24 @@ GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstP
|
||||
interest->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
|
||||
}
|
||||
|
||||
//add by ljq
|
||||
if (firstPkt.has<lp::PTagField>()) {
|
||||
interest->setTag(make_shared<lp::PTag>(firstPkt.get<lp::PTagField>()));
|
||||
}
|
||||
|
||||
if (firstPkt.has<lp::PathidTagField>()) {
|
||||
interest->setTag(make_shared<lp::PathidTag>(firstPkt.get<lp::PathidTagField>()));
|
||||
}
|
||||
|
||||
if (firstPkt.has<lp::RpTagField>()) {
|
||||
interest->setTag(make_shared<lp::RpTag>(firstPkt.get<lp::RpTagField>()));
|
||||
}
|
||||
|
||||
if (firstPkt.has<lp::RsTagField>()) {
|
||||
interest->setTag(make_shared<lp::RsTag>(firstPkt.get<lp::RsTagField>()));
|
||||
}
|
||||
//
|
||||
|
||||
if (m_options.enableGeoTags && firstPkt.has<lp::GeoTagField>()) {
|
||||
interest->setTag(make_shared<lp::GeoTag>(firstPkt.get<lp::GeoTagField>()));
|
||||
}
|
||||
@@ -473,6 +513,25 @@ GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
|
||||
}
|
||||
}
|
||||
|
||||
//add by ljq
|
||||
|
||||
data->setTag(make_shared<lp::PTag>(m_options.C));
|
||||
|
||||
|
||||
if (firstPkt.has<lp::PathidTagField>()) {
|
||||
data->setTag(make_shared<lp::PathidTag>(firstPkt.get<lp::PathidTagField>()));
|
||||
}
|
||||
|
||||
if (firstPkt.has<lp::RpTagField>()) {
|
||||
data->setTag(make_shared<lp::RpTag>(firstPkt.get<lp::RpTagField>()));
|
||||
}
|
||||
|
||||
if (firstPkt.has<lp::RsTagField>()) {
|
||||
data->setTag(make_shared<lp::RsTag>(firstPkt.get<lp::RsTagField>()));
|
||||
}
|
||||
//
|
||||
|
||||
|
||||
this->receiveData(*data, endpointId);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,8 @@ public:
|
||||
* To enable, set value of enableGeoTags option to a function that generates `shared_ptr<GeoTag>`
|
||||
*/
|
||||
std::function<std::shared_ptr<ndn::lp::GeoTag>()> enableGeoTags;
|
||||
|
||||
uint64_t C = 100000000;
|
||||
};
|
||||
|
||||
/** \brief counters provided by GenericLinkService
|
||||
|
||||
@@ -0,0 +1,554 @@
|
||||
|
||||
|
||||
#include "mircc-consumer.hpp"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/string.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/integer.h"
|
||||
#include "ns3/double.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("ndn.ConsumerMIRCC");
|
||||
|
||||
namespace ns3 {
|
||||
namespace ndn {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED(ConsumerMIRCC);
|
||||
|
||||
TypeId
|
||||
ConsumerMIRCC::GetTypeId(void)
|
||||
{
|
||||
static TypeId tid =
|
||||
TypeId("ns3::ndn::ConsumerMIRCC")
|
||||
.SetGroupName("Ndn")
|
||||
.SetParent<Consumer>()
|
||||
.AddConstructor<ConsumerMIRCC>()
|
||||
|
||||
.AddAttribute("MaxSeq", "Maximum sequence number to request",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::m_seqMax), MakeIntegerChecker<uint32_t>())
|
||||
.AddAttribute("appid", "app id",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::appid), MakeIntegerChecker<uint32_t>())
|
||||
.AddAttribute("logtms", "log t ms",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::logtms), MakeIntegerChecker<uint32_t>())
|
||||
.AddAttribute("start_ms", "start time ms",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::m_start_ms), MakeIntegerChecker<uint32_t>())
|
||||
.AddAttribute("end_ms", "end time ms",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::m_end_ms), MakeIntegerChecker<uint32_t>())
|
||||
.AddAttribute("greedy_ms", "start_greedy_ms",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::greedy_ms), MakeIntegerChecker<uint32_t>())
|
||||
.AddAttribute("greedy_rate", "greedy_rate",
|
||||
IntegerValue(std::numeric_limits<uint32_t>::max()),
|
||||
MakeIntegerAccessor(&ConsumerMIRCC::greedy_rate), MakeIntegerChecker<uint32_t>())
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
ConsumerMIRCC::ConsumerMIRCC()
|
||||
: m_frequency(1.0)
|
||||
, m_firstTime(true)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_seqMax = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
ConsumerMIRCC::~ConsumerMIRCC()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConsumerMIRCC::ScheduleNextPacket()
|
||||
{
|
||||
std::printf("");
|
||||
// double mean = 8.0 * m_payloadSize / m_desiredRate.GetBitRate ();
|
||||
// std::cout << "next: " << Simulator::Now().ToDouble(Time::S) + mean << "s\n";
|
||||
/*
|
||||
if (m_firstTime) {
|
||||
m_sendEvent = Simulator::Schedule(Seconds(0.0), &Consumer::, this);
|
||||
m_firstTime = false;
|
||||
}
|
||||
else if (!m_sendEvent.IsRunning())
|
||||
m_sendEvent = Simulator::Schedule((m_random == 0) ? Seconds(1.0 / m_frequency)
|
||||
: Seconds(m_random->GetValue()),
|
||||
&Consumer::SendPacket, this);*/
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC:: StopApplication()
|
||||
{
|
||||
//获取发送事件表的迭代器
|
||||
auto it = pathId2EventId_p.begin();
|
||||
|
||||
//遍历发送事件表
|
||||
while(it != pathId2EventId_p.end())
|
||||
{
|
||||
//取消发送事件
|
||||
EventId tmp = it->second;
|
||||
Simulator::Cancel(tmp);
|
||||
|
||||
//迭代器后移
|
||||
it++;
|
||||
}
|
||||
|
||||
|
||||
auto it2 = pathId2EventId_s.begin();
|
||||
|
||||
//遍历发送事件表
|
||||
while(it2 != pathId2EventId_s.end())
|
||||
{
|
||||
//取消发送事件
|
||||
EventId tmp = it2->second;
|
||||
Simulator::Cancel(tmp);
|
||||
|
||||
//迭代器后移
|
||||
it2++;
|
||||
}
|
||||
|
||||
Simulator::Cancel(explore_event);
|
||||
Simulator::Cancel(log_event);
|
||||
// 调用父类停止face等接口服务
|
||||
App::StopApplication();
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC:: mircclog()
|
||||
{
|
||||
log_event = Simulator::Schedule(Seconds((double)logtms/1000), &ConsumerMIRCC::mircclog, this);
|
||||
double time = logcnt * (double)logtms / 1000;
|
||||
|
||||
std::ofstream ofs;
|
||||
logcnt += 1;
|
||||
if (logcnt == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ofs.open(std::to_string(appid) + ".txt",std::ios::app);
|
||||
|
||||
ofs << time << " Src1 258 appFace:// OutData " << pktcnt_p / ((double)logtms / 1000) << " " << pktcnt_p * 1.024 / ((double)logtms / 1000)<< " " << pktcnt_p << " " << pktcnt_p * 1.024 << std::endl;
|
||||
pktcnt_p = 0;
|
||||
ofs << time << " Src1 259 appFace:// OutData " << pktcnt_s / ((double)logtms / 1000) << " " << pktcnt_s * 1.024 / ((double)logtms / 1000)<< " " << pktcnt_s << " " << pktcnt_s * 1.024 << std::endl;
|
||||
pktcnt_s = 0;
|
||||
|
||||
//
|
||||
ofs << time << " Src1 260 appFace:// OutInterests " << inscnt_p / ((double)logtms / 1000) << " " << 0 << " " << inscnt_p << " " << 0 << std::endl;
|
||||
inscnt_p = 0;
|
||||
ofs << time << " Src1 261 appFace:// OutInterests " << inscnt_s / ((double)logtms / 1000) << " " << 0 << " " << inscnt_s << " " << 0 << std::endl;
|
||||
inscnt_s = 0;
|
||||
ofs << time << " Src1 262 appFace:// OutInterests " << schcnt_p / ((double)logtms / 1000) << " " << 0 << " " << schcnt_p << " " << 0 << std::endl;
|
||||
schcnt_p = 0;
|
||||
ofs << time << " Src1 263 appFace:// OutInterests " << schcnt_s / ((double)logtms / 1000) << " " << 0 << " " << schcnt_s << " " << 0 << std::endl;
|
||||
//
|
||||
|
||||
if (appid == 1)
|
||||
{
|
||||
for (auto it = pathId2EventId_p.begin();it != pathId2EventId_p.end();it++)
|
||||
{
|
||||
NS_LOG_DEBUG("delay" << Simulator::GetDelayLeft(it->second));
|
||||
}
|
||||
}
|
||||
|
||||
schcnt_s = 0;
|
||||
ofs.close();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConsumerMIRCC:: StartApplication()
|
||||
{
|
||||
|
||||
// 调用父类开启face等接口服务
|
||||
App::StartApplication();
|
||||
|
||||
log_event = Simulator::Schedule(Seconds((double)logtms/1000), &ConsumerMIRCC::mircclog, this);
|
||||
std::ofstream ofs;
|
||||
ofs.open(std::to_string(appid) + ".txt",std::ios::app);
|
||||
ofs << "Time Node FaceId FaceDescr Type Packets Kilobytes PacketRaw KilobytesRaw" << std::endl;
|
||||
ofs.close();
|
||||
|
||||
// 调用路径探索
|
||||
if (pathId2RandomId.size() == 0)
|
||||
{//如果节点刚开始运行
|
||||
//尝试利用随机数探索路径
|
||||
explore_event = Simulator::Schedule(Seconds((double)m_start_ms / 1000 + 0.0000001), &ConsumerMIRCC::PathExplorate, this);
|
||||
Simulator::Schedule(Seconds((double)m_end_ms / 1000 + 0.0000001), &ConsumerMIRCC::StopApplication, this);
|
||||
if (greedy_rate != 0)
|
||||
{
|
||||
Simulator::Schedule(Seconds((double)greedy_ms / 1000 + 0.0000001), &ConsumerMIRCC::StartGreedy, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC ::StartGreedy()
|
||||
{
|
||||
m_greedy_tag = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC ::recordSeq(uint64_t seq,uint64_t randId)
|
||||
{//记录seq到当时使用的randId
|
||||
seq2RandomId[seq] = randId;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC ::SendPacket(uint64_t pathId,uint64_t classId)
|
||||
{
|
||||
if (!m_active)
|
||||
return;
|
||||
// if (appid == 1)
|
||||
// NS_LOG_DEBUG("MIRCC SendPacket");
|
||||
uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid
|
||||
|
||||
//处理重传兴趣包
|
||||
//所以重传未必是用之前的子流重传,可能是新的子流
|
||||
//所以重传的兴趣包为一类还是二类完全随机,目前没有固定策略
|
||||
while (m_retxSeqs.size())
|
||||
{
|
||||
//取出第一个要重传的兴趣包
|
||||
seq = *m_retxSeqs.begin();
|
||||
//从重传队列删除
|
||||
m_retxSeqs.erase(m_retxSeqs.begin());
|
||||
break;
|
||||
}
|
||||
|
||||
if (seq == std::numeric_limits<uint32_t>::max())
|
||||
{//如果没有需要重传的数据包
|
||||
if (m_seqMax != std::numeric_limits<uint32_t>::max())
|
||||
{
|
||||
if (m_seq >= m_seqMax)
|
||||
{//已经把需要的序列号兴趣包都发完了
|
||||
return; // we are totally done
|
||||
}
|
||||
}
|
||||
|
||||
//没有重传数据包的前提下,顺次获取下一个需要发送的序号
|
||||
seq = m_seq++;
|
||||
}
|
||||
//
|
||||
seq2P[seq] = classId;
|
||||
|
||||
|
||||
if (classId == 1)
|
||||
{
|
||||
inscnt_p += 1;
|
||||
}else
|
||||
{
|
||||
inscnt_s += 1;
|
||||
}
|
||||
//
|
||||
shared_ptr<Name> nameWithSequence = make_shared<Name>(m_interestName);
|
||||
nameWithSequence->appendSequenceNumber(seq);
|
||||
//
|
||||
|
||||
// shared_ptr<Interest> interest = make_shared<Interest> ();
|
||||
shared_ptr<Interest> interest = make_shared<Interest>();
|
||||
interest->setNonce(m_rand->GetValue(0, std::numeric_limits<uint32_t>::max()));
|
||||
interest->setName(*nameWithSequence);
|
||||
interest->setCanBePrefix(false);
|
||||
time::milliseconds interestLifeTime(m_interestLifeTime.GetMilliSeconds());
|
||||
interest->setInterestLifetime(interestLifeTime);
|
||||
|
||||
//获取对应PathId(子流)对应的RandId。
|
||||
uint64_t tmpRandId;
|
||||
if (pathId != 0)
|
||||
{
|
||||
tmpRandId = pathId2RandomId[pathId];
|
||||
}else
|
||||
{
|
||||
tmpRandId = m_rand->GetValue(0.00001, std::numeric_limits<uint32_t>::max());
|
||||
}
|
||||
//将RandId作为Tag设置到interest包中。
|
||||
interest->setTag(make_shared<lp::PathidTag>(tmpRandId));
|
||||
interest->setTag(make_shared<lp::PTag>(classId));
|
||||
|
||||
//如果判断发现是随机数探索,则记录seq和随机数,用来收到data后把随机数和pathid绑定。
|
||||
if (pathId == 0)
|
||||
{
|
||||
recordSeq(seq,tmpRandId);
|
||||
}
|
||||
|
||||
|
||||
WillSendOutInterest(seq);
|
||||
|
||||
m_transmittedInterests(interest, this, m_face);
|
||||
m_appLink->onReceiveInterest(*interest);
|
||||
|
||||
//这个函数只负责发包,不在负责调用下一个包的发送
|
||||
//ScheduleNextPacket();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ConsumerMIRCC:: SumRp()
|
||||
{
|
||||
//获取遍历所有Rp的迭代器
|
||||
auto it = pathId2Rp.begin();
|
||||
uint64_t res = 0;
|
||||
//遍历所有Rp的迭代器
|
||||
while (it != pathId2Rp.end())
|
||||
{
|
||||
res += it->second;
|
||||
it++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ConsumerMIRCC:: MaxRp()
|
||||
{
|
||||
//获取遍历所有Rp的迭代器
|
||||
auto it = pathId2Rp.begin();
|
||||
uint64_t res = 0;
|
||||
//遍历所有Rp的迭代器
|
||||
while (it != pathId2Rp.end())
|
||||
{
|
||||
res = std::max(res,it->second);
|
||||
it++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC:: SchedulePacketForPathId(uint64_t pathId,uint64_t classId)
|
||||
{
|
||||
SendPacket(pathId,classId);
|
||||
if (classId == 1)
|
||||
{//发送第一类兴趣包,参考当先path的Rp在所有Rp之和的占比 乘上最大Rp
|
||||
uint64_t tmpRp;
|
||||
if (m_greedy_tag == 0)
|
||||
{
|
||||
tmpRp = pathId2Rp[pathId] * MaxRp() / std::max(SumRp(),(uint64_t)1) ;
|
||||
tmpRp = std::max(tmpRp,DATA_SIZE);
|
||||
}else
|
||||
{
|
||||
tmpRp = pathId2Rp[pathId] * greedy_rate / std::max(SumRp(),(uint64_t)1) ;
|
||||
tmpRp = std::max(tmpRp,DATA_SIZE);
|
||||
}
|
||||
|
||||
schcnt_p += 1;
|
||||
pathId2EventId_p[pathId] = Simulator::Schedule(Seconds(1.0 / (tmpRp / DATA_SIZE)), &ConsumerMIRCC::SchedulePacketForPathId,this, pathId,classId);
|
||||
|
||||
}else
|
||||
{//发送第二类兴趣包
|
||||
uint64_t tmpRs ;
|
||||
if (m_greedy_tag == 0)
|
||||
{
|
||||
tmpRs = pathId2Rs[pathId];
|
||||
tmpRs = std::max(tmpRs,DATA_SIZE);
|
||||
}else
|
||||
{
|
||||
return;
|
||||
}
|
||||
schcnt_s += 1;
|
||||
|
||||
|
||||
pathId2EventId_s[pathId] = Simulator::Schedule(Seconds(1.0 / (tmpRs / DATA_SIZE)), &ConsumerMIRCC::SchedulePacketForPathId,this, pathId,classId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC:: PathExplorate()
|
||||
{
|
||||
//路径探索的兴趣包全部标为第一类,原论文没有明确说,但是我觉得这样更合理
|
||||
//因为用于路径探索的兴趣包很重要,如果被丢掉了,consumer可能迟迟无法开始正式发送兴趣包
|
||||
if (appid == 1)
|
||||
NS_LOG_DEBUG("PahtExplorate");
|
||||
if (appid == 1)
|
||||
for (auto i = pathId2RandomId.begin();i != pathId2RandomId.end();i++)
|
||||
{
|
||||
|
||||
NS_LOG_DEBUG("pathId" << i->first << " RandId" << i->second);
|
||||
NS_LOG_DEBUG("Rp" << pathId2Rp[i->first] << " Rs" << pathId2Rs[i->first]);
|
||||
}
|
||||
explore_event = Simulator::Schedule(Seconds(0.1), &ConsumerMIRCC::PathExplorate, this);
|
||||
|
||||
|
||||
//PathId为0表示正在进行路径探索
|
||||
SendPacket(0,1);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC::tryBindRandId(uint64_t seq, uint64_t pathId)
|
||||
{
|
||||
if (seq2RandomId.find(seq) == seq2RandomId.end())
|
||||
{
|
||||
//没有找到seq对应的需要绑定的pathId
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathId2RandomId.find(pathId) != pathId2RandomId.end())
|
||||
{
|
||||
//随机数对应了一条已经找到对应随机数的pathid,没有发现新路径
|
||||
return;
|
||||
}
|
||||
//将随机数绑定到pathid上
|
||||
pathId2RandomId[pathId] = seq2RandomId[seq];
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC::try_refresh_p(uint64_t pathId,uint64_t Rp)
|
||||
{
|
||||
|
||||
if (pathId2EventId_p.find(pathId) == pathId2EventId_p.end())
|
||||
{
|
||||
uint64_t tmpRp = Rp * MaxRp() / std::max(SumRp(),(uint64_t)1);
|
||||
tmpRp = std::max(tmpRp,DATA_SIZE);
|
||||
pathId2EventId_p[pathId] = Simulator::Schedule(Seconds(1.0 / (tmpRp / DATA_SIZE)), &ConsumerMIRCC::SchedulePacketForPathId,this, pathId,1);
|
||||
return;
|
||||
}
|
||||
|
||||
auto tmp1 = Simulator::GetDelayLeft(pathId2EventId_p[pathId]);
|
||||
|
||||
|
||||
uint64_t tmpRp = Rp * MaxRp() / std::max(SumRp(),(uint64_t)1);
|
||||
tmpRp = std::max(tmpRp,DATA_SIZE);
|
||||
Time tmp2 = Seconds(1.0 / (tmpRp / DATA_SIZE));
|
||||
|
||||
if (tmp1 > tmp2)
|
||||
{
|
||||
Simulator::Cancel(pathId2EventId_p[pathId]);
|
||||
pathId2EventId_p[pathId] = Simulator::Schedule(Seconds(1.0 / (tmpRp / DATA_SIZE)), &ConsumerMIRCC::SchedulePacketForPathId,this, pathId,1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConsumerMIRCC::try_refresh_s(uint64_t pathId,uint64_t Rs)
|
||||
{
|
||||
if (pathId2EventId_s.find(pathId) == pathId2EventId_s.end())
|
||||
{
|
||||
uint64_t tmpRs = Rs;
|
||||
tmpRs = std::max(tmpRs,DATA_SIZE);
|
||||
pathId2EventId_s[pathId] = Simulator::Schedule(Seconds(1.0 / (tmpRs / DATA_SIZE)), &ConsumerMIRCC::SchedulePacketForPathId,this, pathId,2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto tmp1 = Simulator::GetDelayLeft(pathId2EventId_s[pathId]);
|
||||
|
||||
|
||||
uint64_t tmpRs = Rs;
|
||||
tmpRs = std::max(tmpRs,DATA_SIZE);
|
||||
Time tmp2 = Seconds(1.0 / (tmpRs / DATA_SIZE));
|
||||
|
||||
if (tmp1 > tmp2)
|
||||
{
|
||||
Simulator::Cancel(pathId2EventId_s[pathId]);
|
||||
pathId2EventId_s[pathId] = Simulator::Schedule(Seconds(1.0 / (tmpRs / DATA_SIZE)), &ConsumerMIRCC::SchedulePacketForPathId,this, pathId,2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ConsumerMIRCC::OnData(shared_ptr<const Data> data)
|
||||
{
|
||||
if (appid == 1)
|
||||
NS_LOG_FUNCTION(this << data);
|
||||
if (!m_active)
|
||||
return;
|
||||
|
||||
App::OnData(data); // tracing inside
|
||||
|
||||
|
||||
// NS_LOG_INFO ("Received content object: " << boost::cref(*data));
|
||||
|
||||
// This could be a problem......
|
||||
uint32_t seq = data->getName().at(-1).toSequenceNumber();
|
||||
// if (appid == 1)
|
||||
//NS_LOG_INFO("< DATA for " << seq);
|
||||
|
||||
//查看当前数据包是否有探索兴趣包产生,如果是的话将探索出的pathid和对应的randId绑定
|
||||
auto tmpPathid = data->getTag<lp::PathidTag>();
|
||||
if (tmpPathid != nullptr)
|
||||
{
|
||||
tryBindRandId(seq, *tmpPathid);
|
||||
}
|
||||
//if (appid == 1)
|
||||
//NS_LOG_DEBUG("seq " << seq << " ClassId " << seq2P[seq]);
|
||||
if (seq2P[seq] == 1)
|
||||
{
|
||||
pktcnt_p += 1;
|
||||
}else
|
||||
{
|
||||
pktcnt_s += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int hopCount = 0;
|
||||
auto hopCountTag = data->getTag<lp::HopCountTag>();
|
||||
if (hopCountTag != nullptr) { // e.g., packet came from local node's cache
|
||||
hopCount = *hopCountTag;
|
||||
}
|
||||
//if (appid == 1)
|
||||
//NS_LOG_DEBUG("Hop count!!: " << hopCount);
|
||||
|
||||
|
||||
uint64_t Rp = 0;
|
||||
auto rpTag = data->getTag<lp::RpTag>();
|
||||
if (rpTag != nullptr)
|
||||
{
|
||||
Rp = *rpTag;
|
||||
}
|
||||
pathId2Rp[*tmpPathid] = Rp;
|
||||
if (appid==1)
|
||||
NS_LOG_INFO("appid=" << appid << "get Rp: " << Rp);
|
||||
|
||||
|
||||
try_refresh_p(*tmpPathid,Rp);
|
||||
|
||||
uint64_t Rs = 0;
|
||||
auto rsTag = data->getTag<lp::RsTag>();
|
||||
if (rsTag != nullptr)
|
||||
{
|
||||
Rs = *rsTag;
|
||||
}
|
||||
pathId2Rs[*tmpPathid] = Rs;
|
||||
if (appid==1)
|
||||
NS_LOG_INFO("appid=" << appid << "get Rs: " << Rs);
|
||||
|
||||
try_refresh_s(*tmpPathid,Rs);
|
||||
|
||||
SeqTimeoutsContainer::iterator entry = m_seqLastDelay.find(seq);
|
||||
if (entry != m_seqLastDelay.end()) {
|
||||
m_lastRetransmittedInterestDataDelay(this, seq, Simulator::Now() - entry->time, hopCount);
|
||||
}
|
||||
|
||||
entry = m_seqFullDelay.find(seq);
|
||||
if (entry != m_seqFullDelay.end()) {
|
||||
m_firstInterestDataDelay(this, seq, Simulator::Now() - entry->time, m_seqRetxCounts[seq], hopCount);
|
||||
}
|
||||
|
||||
m_seqRetxCounts.erase(seq);
|
||||
m_seqFullDelay.erase(seq);
|
||||
m_seqLastDelay.erase(seq);
|
||||
|
||||
m_seqTimeouts.erase(seq);
|
||||
m_retxSeqs.erase(seq);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}// namespace ndn
|
||||
} // namespace ns3
|
||||
@@ -0,0 +1,123 @@
|
||||
|
||||
|
||||
#ifndef NDN_CONSUMER_MIRCC_H
|
||||
#define NDN_CONSUMER_MIRCC_H
|
||||
|
||||
#include "ns3/ndnSIM/model/ndn-common.hpp"
|
||||
|
||||
#include "ndn-consumer.hpp"
|
||||
#include <unordered_map>
|
||||
#include <ndn-cxx/lp/tags.hpp>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
namespace ndn {
|
||||
|
||||
/**
|
||||
* @ingroup ndn-apps
|
||||
* @brief Ndn application for sending out Interest packets at a "constant" rate (Poisson process)
|
||||
*/
|
||||
class ConsumerMIRCC : public Consumer {
|
||||
public:
|
||||
static TypeId
|
||||
GetTypeId();
|
||||
|
||||
/**
|
||||
* \brief Default constructor
|
||||
* Sets up randomizer function and packet sequence number
|
||||
*/
|
||||
ConsumerMIRCC();
|
||||
virtual ~ConsumerMIRCC();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Constructs the Interest packet and sends it using a callback to the underlying NDN
|
||||
* protocol
|
||||
*/
|
||||
virtual void
|
||||
ScheduleNextPacket();
|
||||
|
||||
|
||||
void
|
||||
StopApplication() override;
|
||||
//相比原有的consumer,MIRCC多个子流同时发送,存在一个eventid表需要关闭。
|
||||
|
||||
void
|
||||
StartApplication() override;
|
||||
//相比原有的consumer,MIRCC第一步为先探索路径,而非直接发送
|
||||
|
||||
//void
|
||||
//SendPacket(uint64_t pathId) override;
|
||||
|
||||
void
|
||||
OnData(shared_ptr<const Data> data) override;
|
||||
|
||||
protected:
|
||||
//这两个目前没有用处
|
||||
double m_frequency; // Frequency of interest packets (in hertz)
|
||||
bool m_firstTime;
|
||||
//
|
||||
Ptr<RandomVariableStream> m_random;
|
||||
std::string m_randomType;
|
||||
|
||||
private:
|
||||
//路径id到发送事件id的一一映射关系
|
||||
std:: unordered_map <uint64_t,EventId> pathId2EventId_p,pathId2EventId_s;
|
||||
|
||||
//路径id到路径随机数的一一映射关系(使用对应路径随机数使得路由器按该路径转发)
|
||||
std:: unordered_map <uint64_t,uint64_t> pathId2RandomId;
|
||||
|
||||
//路径id到该路径Rp的一一映射关系
|
||||
std:: unordered_map <uint64_t,uint64_t> pathId2Rp;
|
||||
|
||||
//路径id到该路径Rs的一一映射关系
|
||||
std:: unordered_map <uint64_t,uint64_t> pathId2Rs;
|
||||
|
||||
//
|
||||
std:: unordered_map <uint64_t,uint64_t> seq2RandomId;
|
||||
//
|
||||
std:: unordered_map <uint64_t,uint64_t> seq2P;
|
||||
|
||||
const uint64_t INTEREST_SIZE = 200,DATA_SIZE = 8696,C = 1000 * 1000;
|
||||
|
||||
uint64_t m_start_ms,m_end_ms,appid,logtms,greedy_ms,greedy_rate,m_greedy_tag = 0,logcnt = 0,pktcnt_p = 0,pktcnt_s = 0,inscnt_p = 0,inscnt_s = 0,schcnt_p = 0,schcnt_s = 0;
|
||||
//利用随机数探索路径
|
||||
void PathExplorate();
|
||||
|
||||
//使用pathId发送
|
||||
void SchedulePacketForPathId(uint64_t pathId,uint64_t classId);
|
||||
|
||||
//计算所有Rp的速率之和
|
||||
uint64_t SumRp();
|
||||
|
||||
|
||||
//计算所有Rp的速率最大值
|
||||
uint64_t MaxRp();
|
||||
|
||||
//记录seq号和随机数,用于绑定pathid和randid。
|
||||
void recordSeq();
|
||||
|
||||
void tryBindRandId(uint64_t seq, uint64_t pathId);
|
||||
|
||||
void recordSeq(uint64_t seq,uint64_t randId);
|
||||
|
||||
void SendPacket(uint64_t pathId,uint64_t classId);
|
||||
|
||||
void try_refresh_p(uint64_t pathId,uint64_t Rp);
|
||||
|
||||
void try_refresh_s(uint64_t pathId,uint64_t Rs);
|
||||
|
||||
void mircclog();
|
||||
|
||||
void StartGreedy();
|
||||
|
||||
EventId explore_event,log_event,greedy_event;
|
||||
};
|
||||
|
||||
|
||||
//注意,目前版本的consumer假设所有节点的FIB不产生变化,否则会产生大量的路径判断未知问题!!!
|
||||
|
||||
} // namespace ndn
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
@@ -282,6 +282,14 @@ StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
|
||||
opts.allowReassembly = true;
|
||||
opts.allowCongestionMarking = true;
|
||||
|
||||
//add by ljq
|
||||
DataRateValue dataRateAttribute;
|
||||
if (netDevice->GetAttributeFailSafe("DataRate", dataRateAttribute)) {
|
||||
auto dataRate = dataRateAttribute.Get();
|
||||
opts.C = dataRate.GetBitRate();
|
||||
}
|
||||
//
|
||||
|
||||
auto linkService = make_unique<::nfd::face::GenericLinkService>(opts);
|
||||
|
||||
auto transport = make_unique<NetDeviceTransport>(node, netDevice,
|
||||
|
||||
@@ -268,6 +268,13 @@ extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
|
||||
if (lpPacket.has<lp::HopCountTagField>()) {
|
||||
netPacket.setTag(make_shared<lp::HopCountTag>(lpPacket.get<lp::HopCountTagField>() + 1));
|
||||
}
|
||||
|
||||
//add by ljq
|
||||
addTagFromField<lp::PTag, lp::PTagField>(netPacket, lpPacket);
|
||||
addTagFromField<lp::PathidTag, lp::PathidTagField>(netPacket, lpPacket);
|
||||
addTagFromField<lp::RpTag, lp::RpTagField>(netPacket, lpPacket);
|
||||
addTagFromField<lp::RsTag, lp::RsTagField>(netPacket, lpPacket);
|
||||
//
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -98,6 +98,13 @@ public: // consumer
|
||||
addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest2);
|
||||
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest2);
|
||||
|
||||
//add by ljq
|
||||
addFieldFromTag<lp::PTagField, lp::PTag>(lpPacket, interest2);
|
||||
addFieldFromTag<lp::PathidTagField, lp::PathidTag>(lpPacket, interest2);
|
||||
addFieldFromTag<lp::RpTagField, lp::RpTag>(lpPacket, interest2);
|
||||
addFieldFromTag<lp::RsTagField, lp::RsTag>(lpPacket, interest2);
|
||||
//
|
||||
|
||||
entry.recordForwarding();
|
||||
m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest2.wireEncode(),
|
||||
'I', interest2.getName()));
|
||||
@@ -230,6 +237,13 @@ public: // producer
|
||||
addFieldFromTag<lp::CachePolicyField, lp::CachePolicyTag>(lpPacket, data);
|
||||
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
|
||||
|
||||
//add by ljq
|
||||
addFieldFromTag<lp::PTagField, lp::PTag>(lpPacket, data);
|
||||
addFieldFromTag<lp::RpTagField, lp::RpTag>(lpPacket, data);
|
||||
addFieldFromTag<lp::RsTagField, lp::RsTag>(lpPacket, data);
|
||||
addFieldFromTag<lp::PathidTagField, lp::PathidTag>(lpPacket, data);
|
||||
//
|
||||
|
||||
m_face.m_transport->send(finishEncoding(std::move(lpPacket), data.wireEncode(),
|
||||
'D', data.getName()));
|
||||
}
|
||||
|
||||
@@ -138,6 +138,31 @@ typedef FieldDecl<field_location_tags::Fragment,
|
||||
tlv::Fragment> FragmentField;
|
||||
BOOST_CONCEPT_ASSERT((Field<FragmentField>));
|
||||
|
||||
|
||||
//add by ljq
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
tlv::PTag> PTagField;
|
||||
BOOST_CONCEPT_ASSERT((Field<PTagField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
tlv::PathidTag> PathidTagField;
|
||||
BOOST_CONCEPT_ASSERT((Field<PathidTagField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
tlv::RpTag> RpTagField;
|
||||
BOOST_CONCEPT_ASSERT((Field<RpTagField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
tlv::RsTag> RsTagField;
|
||||
BOOST_CONCEPT_ASSERT((Field<RsTagField>));
|
||||
//
|
||||
|
||||
|
||||
|
||||
/** \brief Set of all field declarations.
|
||||
*/
|
||||
typedef boost::mpl::set<
|
||||
@@ -156,7 +181,13 @@ typedef boost::mpl::set<
|
||||
NonDiscoveryField,
|
||||
PrefixAnnouncementField,
|
||||
HopCountTagField,
|
||||
GeoTagField
|
||||
GeoTagField,
|
||||
//add by ljq
|
||||
RsTagField,
|
||||
RpTagField,
|
||||
PathidTagField,
|
||||
PTagField
|
||||
//
|
||||
> FieldSet;
|
||||
|
||||
} // namespace lp
|
||||
|
||||
@@ -80,6 +80,17 @@ typedef SimpleTag<PrefixAnnouncementHeader, 15> PrefixAnnouncementTag;
|
||||
*/
|
||||
typedef SimpleTag<uint64_t, 0x60000000> HopCountTag;
|
||||
|
||||
//add by ljq
|
||||
typedef SimpleTag<uint64_t, 16> PTag;
|
||||
|
||||
typedef SimpleTag<uint64_t, 17> PathidTag;
|
||||
|
||||
typedef SimpleTag<uint64_t, 18> RpTag;
|
||||
|
||||
typedef SimpleTag<uint64_t, 19> RsTag;
|
||||
//
|
||||
|
||||
|
||||
/** \class GeoTag
|
||||
* \brief a packet tag for GeoTag field
|
||||
*
|
||||
|
||||
@@ -50,6 +50,12 @@ enum {
|
||||
TxSequence = 840,
|
||||
NonDiscovery = 844,
|
||||
PrefixAnnouncement = 848,
|
||||
//add by ljq
|
||||
PTag = 852,
|
||||
PathidTag = 856,
|
||||
RpTag = 890,
|
||||
RsTag = 894
|
||||
//
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
@@ -0,0 +1,646 @@
|
||||
<a name="ugSXa"></a>
|
||||
## 1. 实验1
|
||||
<a name="les0v"></a>
|
||||
### 1.1 场景设置
|
||||
|
||||
- 拓扑
|
||||
```bash
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
ER1 NA 10 10
|
||||
CR1 NA 10 12
|
||||
CR2 NA 10 14
|
||||
ER2 NA 10 16
|
||||
P1 NA 13 18
|
||||
P2 NA 11 18
|
||||
P3 NA 9 18
|
||||
P4 NA 7 18
|
||||
C1 NA 13 8
|
||||
C2 NA 11 8
|
||||
C3 NA 9 8
|
||||
C4 NA 7 8
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
ER2 P1 100Mbps 1 10ms 20
|
||||
ER2 P2 100Mbps 1 10ms 20
|
||||
ER2 P3 100Mbps 1 10ms 20
|
||||
ER2 P4 100Mbps 1 10ms 20
|
||||
CR2 ER2 100Mbps 1 10ms 20
|
||||
ER1 CR1 100Mbps 1 10ms 20
|
||||
CR1 CR2 10Mbps 1 10ms 20
|
||||
C1 ER1 100Mbps 1 10ms 20
|
||||
C2 ER1 100Mbps 1 10ms 20
|
||||
C3 ER1 100Mbps 1 10ms 20
|
||||
C4 ER1 100Mbps 1 10ms 20
|
||||
```
|
||||

|
||||
|
||||
- 参数设置
|
||||
|
||||
为了评估我们提出的区分服务模型,使用如图所示的哑铃型拓扑。使用四种不同的服务等级:EF、AF2、AF1、BE,每个服务类别有10个consumer请求,consumer的兴趣包生成速率服从xx为xx的泊松分布(当前未采用),请求内容的流行度服从q=0.7, s=0.7(q => parameter of improve rank, s => parameter of power)的zipf分布。其中,EF对应时延敏感流,限制其总速率不超过1Mbps(语音流,每个客户端100Kbps),假设AF2、AF1、BE的优先级之比为3:2:1。核心网瓶颈链路的带宽为10Mbps。在网络上部署我们的机制。根据我们的QoS管理方案和拥塞控制机制,每个服务等级在瓶颈链路的理论约定速率为1Mbps : 4.5Mbps : 3Mbps : 1.5Mbps。<br />**指标:**吞吐量(求和)、时延(均值)、丢包率(求和)、抖动(均值,待定)。<br />**备选曲线:**CDF<br />----------------------------------------------------<br />代码中是40个客户端分别请求40个内容<br />运行120s
|
||||
<a name="xJkPa"></a>
|
||||
### 1.2 DSCCP方案结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="No50S"></a>
|
||||
### 1.3 PCON结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="zobsi"></a>
|
||||
## 2. 实验2
|
||||
<a name="pnKqj"></a>
|
||||
### 2.1 场景设置
|
||||
|
||||
- 拓扑
|
||||
```bash
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
R1 NA 5 5
|
||||
C1 NA 7 3
|
||||
C2 NA 5 3
|
||||
C3 NA 3 3
|
||||
R2 NA 6 7
|
||||
R3 NA 4 7
|
||||
P1 NA 7 9
|
||||
P2 NA 5 9
|
||||
P3 NA 4 9
|
||||
P4 NA 3 9
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
C1 R1 100Mbps 1 10ms 20
|
||||
C2 R1 100Mbps 1 10ms 20
|
||||
C3 R1 100Mbps 1 10ms 20
|
||||
R1 R2 5Mbps 1 10ms 20
|
||||
R1 R3 5Mbps 1 5ms 20
|
||||
R2 P1 100Mbps 1 10ms 20
|
||||
R3 P2 100Mbps 1 10ms 20
|
||||
R3 P3 100Mbps 1 10ms 20
|
||||
R3 P4 100Mbps 1 10ms 20
|
||||
```
|
||||

|
||||
|
||||
- 参数设置
|
||||
|
||||
仿真时间为120秒。三个客户端的优先级为EF(固定约定速率为1Mbps);AF1、BE(2:1)。每个客户端有两条不同的路到达生产者。EF从0秒就启动,90秒种停止。AF1从第30秒启动、BE从第60秒启动,一直到结束。Zipf分布,NumberofPacket = 10w<br />**指标:**吞吐量、时延、丢包率、抖动(待定)。<br />**备选曲线:**CDF
|
||||
|
||||
<a name="ZveFB"></a>
|
||||
### 2.2 DSCCP方案结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
<a name="feifS"></a>
|
||||
## 3. 实验3
|
||||
<a name="FGnRZ"></a>
|
||||
### 3.1 场景一
|
||||
<a name="XqRxj"></a>
|
||||
#### 3.1.1 场景设置
|
||||
|
||||
- 拓扑
|
||||
```bash
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
R1 NA 5 3
|
||||
R2 NA 5 5
|
||||
R4 NA 5 7
|
||||
R6 NA 5 9
|
||||
C1 NA 7 1
|
||||
C2 NA 5 1
|
||||
C3 NA 3 1
|
||||
P1 NA 8 11
|
||||
P2 NA 6 11
|
||||
P3 NA 4 11
|
||||
P4 NA 2 11
|
||||
R3 NA 7 8
|
||||
R5 NA 3 8
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
C1 R1 100Mbps 1 10ms 20
|
||||
C2 R1 100Mbps 1 10ms 20
|
||||
C3 R1 100Mbps 1 10ms 20
|
||||
R6 P1 100Mbps 1 10ms 20
|
||||
R6 P2 100Mbps 1 10ms 20
|
||||
R6 P3 100Mbps 1 10ms 20
|
||||
R6 P4 100Mbps 1 10ms 20
|
||||
R1 R2 8Mbps 1 10ms 20
|
||||
R2 R3 1Mbps 1 10ms 20
|
||||
R4 R3 2Mbps 1 5ms 20
|
||||
R3 R6 3Mbps 1 10ms 20
|
||||
R4 R5 3Mbps 1 5ms 20
|
||||
R2 R4 5Mbps 1 5ms 20
|
||||
R2 R5 4Mbps 1 10ms 20
|
||||
R5 R6 7Mbps 1 10ms 20
|
||||
```
|
||||

|
||||
|
||||
- 参数设置
|
||||
- 四条路的带宽分别为1Mbps、2Mbps、3Mbps和4Mbps,时延均一样
|
||||
- 三个客户端优先级一致(AF2),仿真时间200s。间隔30s加入。C3在150秒的时候开始贪婪。
|
||||
<a name="dhpN3"></a>
|
||||
#### 3.1.2 DSCCP方案结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="wD6qS"></a>
|
||||
#### 3.1.3 PCON 结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="ps3fV"></a>
|
||||
|
||||
#### 3.1.4 OMCC-RF 结果
|
||||
参数:pMax = 0.02, beta = 0.95
|
||||
> pMax => 最大窗口下降概率
|
||||
> beta => 窗口乘性递减因子
|
||||
> [OMCC-RF](https://www.yuque.com/u25297296/ma2q2x/xqylql)
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="Sputt"></a>
|
||||
### 3.2 场景2
|
||||
<a name="kBQTN"></a>
|
||||
#### 3.2.1 场景设置
|
||||
|
||||
- 拓扑
|
||||
```bash
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
R1 NA 5 3
|
||||
R2 NA 5 5
|
||||
R4 NA 5 7
|
||||
R6 NA 5 9
|
||||
C1 NA 7 1
|
||||
C2 NA 5 1
|
||||
C3 NA 3 1
|
||||
P1 NA 8 11
|
||||
P2 NA 6 11
|
||||
P3 NA 4 11
|
||||
P4 NA 2 11
|
||||
R3 NA 7 8
|
||||
R5 NA 3 8
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
C1 R1 100Mbps 1 10ms 20
|
||||
C2 R1 100Mbps 1 10ms 20
|
||||
C3 R1 100Mbps 1 10ms 20
|
||||
R6 P1 100Mbps 1 10ms 20
|
||||
R6 P2 100Mbps 1 10ms 20
|
||||
R6 P3 100Mbps 1 10ms 20
|
||||
R6 P4 100Mbps 1 10ms 20
|
||||
R1 R2 8Mbps 1 10ms 20
|
||||
R5 R6 5Mbps 1 10ms 20
|
||||
R2 R3 2.5Mbps 1 10ms 20
|
||||
R2 R4 5Mbps 1 10ms 20
|
||||
R3 R6 5Mbps 1 5ms 20
|
||||
R4 R3 2.5Mbps 1 5ms 20
|
||||
R4 R5 2.5Mbps 1 5ms 20
|
||||
R2 R5 2.5Mbps 1 20ms 20
|
||||
```
|
||||

|
||||
|
||||
- 参数设置
|
||||
> Zipf 分布去掉惹,因为PCON使用zipf分布不太正常~
|
||||
|
||||
- 每条路的**带宽都一致 => 2Mbps**;
|
||||
- R2 -> R6 的四条路的**时延依次为:15ms、20ms、25ms、30ms;**
|
||||
- 三个客户端优先级一致(AF2),仿真时间200s。间隔30s加入。C3在150秒的时候开始贪婪。
|
||||
<a name="BSJLs"></a>
|
||||
#### 3.2.2 DSCCP结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="WDP8z"></a>
|
||||
#### 3.2.3 PCON结果
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="FsQxd"></a>
|
||||
#### 3.2.4 OMCC-RF 结果
|
||||
参数:pMax = 0.02, beta = 0.95
|
||||
> pMax => 最大窗口下降概率
|
||||
> beta => 窗口乘性递减因子
|
||||
> [OMCC-RF](https://www.yuque.com/u25297296/ma2q2x/xqylql)
|
||||
|
||||
- 吞吐量
|
||||
|
||||

|
||||
|
||||
- 吞吐量merge
|
||||
|
||||

|
||||
|
||||
- 延迟
|
||||
|
||||

|
||||
|
||||
- 丢包
|
||||
|
||||

|
||||
<a name="QBgB4"></a>
|
||||
## 4. 实验4
|
||||
> <a name="tL0VX"></a>
|
||||
### Abliene拓扑 (真实网络拓扑1)
|
||||
|
||||
<br />实验四整体采用上述 Abliene 拓扑,其中实线代表单径场景下的路由配置,多径场景则加上虚线所指的路由配置。
|
||||
<a name="Aukjm"></a>
|
||||
### 4.1 场景一(单径测试)
|
||||
<a name="Hr0CR"></a>
|
||||
#### 4.1.1 场景设置
|
||||
|
||||
- 拓扑
|
||||
```bash
|
||||
# topo_abilene.txt
|
||||
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
C1 NA 3 7
|
||||
C2 NA 1 4
|
||||
C3 NA 1 3
|
||||
C4 NA 3 1
|
||||
C5 NA 5 1
|
||||
C6 NA 6 3
|
||||
C7 NA 6 5
|
||||
C8 NA 4 7
|
||||
R0 NA 3 6
|
||||
R1 NA 2 5
|
||||
R2 NA 2 4
|
||||
R3 NA 2 3
|
||||
R4 NA 3 2
|
||||
R5 NA 4 2
|
||||
R6 NA 5 2
|
||||
R7 NA 5 3
|
||||
R8 NA 5 4
|
||||
R9 NA 5 5
|
||||
R10 NA 4 6
|
||||
P1 NA 1 5
|
||||
P2 NA 4 1
|
||||
P3 NA 6 4
|
||||
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
C1 R0 100Mbps 1 10ms 20
|
||||
R1 P1 100Mbps 1 10ms 20
|
||||
R2 C2 100Mbps 1 10ms 20
|
||||
R3 C3 100Mbps 1 10ms 20
|
||||
R4 C4 100Mbps 1 10ms 20
|
||||
R5 P2 100Mbps 1 10ms 20
|
||||
R6 C5 100Mbps 1 10ms 20
|
||||
R7 C6 100Mbps 1 10ms 20
|
||||
R8 P3 100Mbps 1 10ms 20
|
||||
R9 C7 100Mbps 1 10ms 20
|
||||
R10 C8 100Mbps 1 10ms 20
|
||||
R0 R1 10Mbps 1 10ms 20
|
||||
R1 R2 25Mbps 1 10ms 20
|
||||
R2 R3 15Mbps 1 10ms 20
|
||||
R3 R4 15Mbps 1 10ms 20
|
||||
R4 R5 20Mbps 1 10ms 20
|
||||
R5 R6 5Mbps 1 10ms 20
|
||||
R6 R7 5Mbps 1 10ms 20
|
||||
R7 R8 10Mbps 1 10ms 20
|
||||
R8 R9 20Mbps 1 10ms 20
|
||||
R9 R10 20Mbps 1 10ms 20
|
||||
R10 R0 10Mbps 1 10ms 20
|
||||
R2 R9 20Mbps 1 10ms 20
|
||||
R3 R8 10Mbps 1 10ms 20
|
||||
R5 R7 15Mbps 1 10ms 20
|
||||
```
|
||||

|
||||
|
||||
- 参数设置
|
||||
- 内容仓库:
|
||||
- P1 => /amazon
|
||||
- P2 => /google
|
||||
- P3 => /warner
|
||||
- 每个内容总共有 **10000 个分片 **,每个数据包的大小为**1087Byte**(1024Byte的负载 + 63Byte的头部);
|
||||
- 客户端节点:
|
||||
- C1 ~ C8
|
||||
- 每个客户端节点均部署三个Consumer,分别请求 /amazon、/google 和 /warner 三个内容。
|
||||
- **每个Consumer在请求到完整的内容后退出**(例如:C1上请求/amazon的Consumer,在拉取到 /amazon 内容的 10000 个分片之后就停止发送Interest)
|
||||
- 实验目标
|
||||
- 测量每个Consumer的内容完成时间;
|
||||
<a name="VWFTD"></a>
|
||||
#### 4.1.2 内容完成时间对比
|
||||
> PCON单径对比DSCCP单径
|
||||
|
||||

|
||||
<a name="U8gw8"></a>
|
||||
#### 4.1.3 吞吐量对比
|
||||
|
||||
- DSCCP producer 吞吐量
|
||||
|
||||

|
||||
|
||||
- PCON producer 吞吐量
|
||||
|
||||

|
||||
|
||||
- OMCC-RF producer 吞吐量
|
||||
|
||||

|
||||
|
||||
- DSCCP、PCON 和 OMCC-RF producer 吞吐量对比
|
||||
|
||||

|
||||
<a name="COjv7"></a>
|
||||
#### 4.1.5 丢包对比
|
||||

|
||||
<a name="OiGq8"></a>
|
||||
### 4.2 场景二(多径测试)
|
||||
<a name="OqC2Y"></a>
|
||||
#### 4.2.1 场景设置
|
||||
场景设置与4.1.1一致,只是路由配置成多径路由
|
||||
<a name="lna8W"></a>
|
||||
#### 4.2.2 内容完成对比
|
||||

|
||||
<a name="hGmfH"></a>
|
||||
#### 4.2.3 吞吐量对比
|
||||
|
||||
- DSCCP producer 吞吐量
|
||||
|
||||

|
||||
|
||||
- PCON producer 吞吐量
|
||||
|
||||

|
||||
|
||||
- OMCC-RF producer 吞吐量
|
||||
|
||||

|
||||
|
||||
- DSCCP、PCON 和 OMCC-RF producer 吞吐量对比
|
||||
|
||||

|
||||
<a name="As3fZ"></a>
|
||||
#### 4.2.5 丢包对比
|
||||

|
||||
<a name="g9AA0"></a>
|
||||
### 4.3 两个场景内容交付时间交叉对比
|
||||

|
||||
<a name="rC37I"></a>
|
||||
## 5. 实验5
|
||||
<br />实验5将采用如图所示的 [Geant-gn4-3n](https://network.geant.org/gn4-3n/) 网络拓扑,具体将采用下面PDF展示的路由配置:<br />[geant-gn4-3n.pdf](https://www.yuque.com/attachments/yuque/0/2022/pdf/25666928/1653797976967-156483f0-81ec-4629-a1bd-bf6a2367e939.pdf)
|
||||
|
||||
- 总共有八个producer
|
||||
- P1(n44)=>提供 /C1
|
||||
- P2(n27)=>提供 /C2
|
||||
- P3(n8)=>提供 /C3
|
||||
- P4(n7)=>提供 /C4
|
||||
- P5(n1)=>提供 /C5
|
||||
- P6(n0)=>提供 /C6
|
||||
- P7(n19)=>提供 /C7
|
||||
- P8(n38)=>提供 /C8
|
||||
- 总共有在八个节点安装了Consumer,每个节点安装8个Consumer,分别请求上述八个内容:
|
||||
- n18
|
||||
- n4
|
||||
- n3
|
||||
- n25
|
||||
- n40
|
||||
- n45
|
||||
- n41
|
||||
- n37
|
||||
<a name="M9EmI"></a>
|
||||
### 5.1 场景一(多径内容交付时间测试)
|
||||
<a name="xlFxN"></a>
|
||||
#### 5.1.1 场景设置
|
||||
|
||||
- 拓扑
|
||||
```bash
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
n5 NA 4 8
|
||||
n3 NA 2 6
|
||||
n6 NA 4 6
|
||||
n4 NA 2 4
|
||||
n7 NA 6 7
|
||||
n8 NA 6 9
|
||||
n9 NA 8 8
|
||||
n10 NA 6 6
|
||||
n11 NA 8 6
|
||||
n12 NA 10 5
|
||||
n13 NA 10 3
|
||||
n14 NA 9 1
|
||||
n15 NA 9 -1
|
||||
n0 NA 3 -1
|
||||
n1 NA 2 1
|
||||
n16 NA 7 -3
|
||||
n17 NA 7 -5
|
||||
n18 NA 5 -5
|
||||
n19 NA 9 -5
|
||||
n20 NA 9 -3
|
||||
n21 NA 12 0
|
||||
n22 NA 12 2
|
||||
n23 NA 12 4
|
||||
n24 NA 12 6
|
||||
n25 NA 10 9
|
||||
n26 NA 12 10
|
||||
n27 NA 14 11
|
||||
n28 NA 14 -2
|
||||
n29 NA 16 -1
|
||||
n30 NA 16 1
|
||||
n31 NA 16 3
|
||||
n32 NA 17 -3
|
||||
n33 NA 18 -1
|
||||
n34 NA 18 1
|
||||
n35 NA 18 3
|
||||
n36 NA 18 5
|
||||
n37 NA 18 -4
|
||||
n38 NA 15 -5
|
||||
n39 NA 20 1
|
||||
n40 NA 20 7
|
||||
n41 NA 20 -2
|
||||
n42 NA 21 5
|
||||
n43 NA 22 7
|
||||
n44 NA 24 7
|
||||
n45 NA 24 1
|
||||
n46 NA 24 3
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
n3 n5 100Mbps 1 10ms 20
|
||||
n5 n6 100Mbps 1 10ms 20
|
||||
n3 n4 100Mbps 1 10ms 20
|
||||
n5 n9 100Mbps 1 10ms 20
|
||||
n6 n10 100Mbps 1 10ms 20
|
||||
n11 n10 100Mbps 1 10ms 20
|
||||
n11 n9 100Mbps 1 10ms 20
|
||||
n11 n12 100Mbps 1 10ms 20
|
||||
n12 n13 100Mbps 1 10ms 20
|
||||
n14 n13 100Mbps 1 10ms 20
|
||||
n14 n15 100Mbps 1 10ms 20
|
||||
n3 n14 100Mbps 1 10ms 20
|
||||
n4 n15 100Mbps 1 10ms 20
|
||||
n15 n16 100Mbps 1 10ms 20
|
||||
n17 n16 100Mbps 1 10ms 20
|
||||
n17 n18 100Mbps 1 10ms 20
|
||||
n20 n16 100Mbps 1 10ms 20
|
||||
n21 n15 100Mbps 1 10ms 20
|
||||
n21 n14 100Mbps 1 10ms 20
|
||||
n22 n14 100Mbps 1 10ms 20
|
||||
n22 n23 100Mbps 1 10ms 20
|
||||
n25 n9 100Mbps 1 10ms 20
|
||||
n25 n26 100Mbps 1 10ms 20
|
||||
n20 n28 100Mbps 1 10ms 20
|
||||
n21 n28 100Mbps 1 10ms 20
|
||||
n29 n30 100Mbps 1 10ms 20
|
||||
n31 n30 100Mbps 1 10ms 20
|
||||
n30 n21 100Mbps 1 10ms 20
|
||||
n22 n31 100Mbps 1 10ms 20
|
||||
n29 n32 100Mbps 1 10ms 20
|
||||
n28 n32 100Mbps 1 10ms 20
|
||||
n33 n32 100Mbps 1 10ms 20
|
||||
n33 n34 100Mbps 1 10ms 20
|
||||
n35 n34 100Mbps 1 10ms 20
|
||||
n35 n36 100Mbps 1 10ms 20
|
||||
n30 n33 100Mbps 1 10ms 20
|
||||
n31 n36 100Mbps 1 10ms 20
|
||||
n33 n37 100Mbps 1 10ms 20
|
||||
n34 n39 100Mbps 1 10ms 20
|
||||
n35 n39 100Mbps 1 10ms 20
|
||||
n36 n40 100Mbps 1 10ms 20
|
||||
n39 n41 100Mbps 1 10ms 20
|
||||
n39 n45 100Mbps 1 10ms 20
|
||||
n46 n45 100Mbps 1 10ms 20
|
||||
n40 n42 100Mbps 1 10ms 20
|
||||
n43 n42 100Mbps 1 10ms 20
|
||||
n0 n15 5Mbps 1 10ms 20
|
||||
n0 n14 5Mbps 1 10ms 20
|
||||
n1 n15 5Mbps 1 10ms 20
|
||||
n1 n14 5Mbps 1 10ms 20
|
||||
n17 n19 5Mbps 1 10ms 20
|
||||
n20 n19 5Mbps 1 10ms 20
|
||||
n38 n28 5Mbps 1 10ms 20
|
||||
n38 n37 5Mbps 1 10ms 20
|
||||
n46 n44 3Mbps 1 10ms 20
|
||||
n39 n44 4Mbps 1 10ms 20
|
||||
n43 n44 3Mbps 1 10ms 20
|
||||
n27 n36 5Mbps 1 10ms 20
|
||||
n27 n26 5Mbps 1 10ms 20
|
||||
n7 n9 5Mbps 1 10ms 20
|
||||
n5 n7 5Mbps 1 10ms 20
|
||||
n8 n9 5Mbps 1 10ms 20
|
||||
n5 n8 5Mbps 1 10ms 20
|
||||
n24 n23 100Mbps 1 10ms 20
|
||||
n24 n12 100Mbps 1 10ms 20
|
||||
n24 n25 100Mbps 1 10ms 20
|
||||
```
|
||||

|
||||
|
||||
- <br />
|
||||
@@ -0,0 +1,426 @@
|
||||
#include "mircc-strategy.hpp"
|
||||
|
||||
NFD_LOG_INIT(MIRCCStrategy);
|
||||
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
|
||||
MIRCCStrategy::MIRCCStrategy(Forwarder &forwarder, const ndn::Name &name)
|
||||
: Strategy(forwarder), ProcessNackTraits<MIRCCStrategy>(this)
|
||||
{
|
||||
this->setInstanceName(makeInstanceName(name, getStrategyName()));
|
||||
time::nanoseconds ttime(1);
|
||||
getScheduler().schedule(ttime, bind(&MIRCCStrategy::mirccinit, this));
|
||||
}
|
||||
|
||||
const Name&
|
||||
MIRCCStrategy::getStrategyName()
|
||||
{
|
||||
static Name strategyName("/localhost/nfd/strategy/mircc/%FD%01");
|
||||
return strategyName;
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::mirccinit()
|
||||
{
|
||||
const FaceTable &faceTable = getFaceTable();
|
||||
for (auto& tmp : faceTable)
|
||||
{
|
||||
//非外部端口跳过
|
||||
if (tmp.getId() < 257)
|
||||
continue;
|
||||
|
||||
m_linkC[inface(tmp.getId())] = 1 * 1000 * 1000;//初始化均为1Mb/s
|
||||
|
||||
m_Rp_base[inface(tmp.getId())] = m_linkC[inface(tmp.getId())];
|
||||
m_Rp_ex[inface(tmp.getId())] = 0;
|
||||
m_Rs_base[inface(tmp.getId())] = 0;
|
||||
m_Rs_ex[inface(tmp.getId())] = 0;
|
||||
|
||||
m_Yp[inface(tmp.getId())] = 0;
|
||||
m_Yp_old[inface(tmp.getId())] = 0;
|
||||
m_Ys[inface(tmp.getId())] = 0;
|
||||
m_Ys_old[inface(tmp.getId())] = 0;
|
||||
|
||||
m_d[inface(tmp.getId())] = 0.03;
|
||||
|
||||
sendQueueInterest(tmp.getId());
|
||||
|
||||
calcRt(tmp.getId());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::sendQueueInterest(FaceId mface)
|
||||
{
|
||||
|
||||
//设置下一次发送,根据兴趣包与数据包的大小之比,计算出兴趣包可用带宽,进而计算出每发送一个兴趣包需要的时间,最小为1ms
|
||||
time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)]));
|
||||
getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface));
|
||||
|
||||
//分三种情况讨论,只有第一类兴趣包可以发,只有第二类兴趣包可以发,两类可以发(选择最早到达的)
|
||||
if (m_Queue[inface(mface)].qp.size() > 0 and m_Queue[inface(mface)].qs.size() == 0)
|
||||
{
|
||||
shared_ptr<Interest> interest = m_Queue[inface(mface)].qp.front();
|
||||
sendInterest(m_Queue[inface(mface)].pp.front(),FaceEndpoint(*getFaceTable().get(mface),0),*interest);
|
||||
m_Queue[inface(mface)].qp.pop_front();
|
||||
m_Queue[inface(mface)].tp.pop_front();
|
||||
m_Queue[inface(mface)].pp.pop_front();
|
||||
|
||||
}else if (m_Queue[inface(mface)].qs.size() > 0 and m_Queue[inface(mface)].qp.size() == 0)
|
||||
{
|
||||
shared_ptr<Interest> interest = m_Queue[inface(mface)].qs.front();
|
||||
sendInterest(m_Queue[inface(mface)].ps.front(),FaceEndpoint(*getFaceTable().get(mface),0),*interest);
|
||||
m_Queue[inface(mface)].qs.pop_front();
|
||||
m_Queue[inface(mface)].ts.pop_front();
|
||||
m_Queue[inface(mface)].ps.pop_front();
|
||||
}else if (m_Queue[inface(mface)].qs.size() > 0 and m_Queue[inface(mface)].qp.size() > 0)
|
||||
{
|
||||
if (m_Queue[inface(mface)].tp.front() < m_Queue[inface(mface)].ts.front())
|
||||
{
|
||||
shared_ptr<Interest> interest =m_Queue[inface(mface)].qp.front();
|
||||
sendInterest(m_Queue[inface(mface)].pp.front(),FaceEndpoint(*getFaceTable().get(mface),0),*interest);
|
||||
m_Queue[inface(mface)].qp.pop_front();
|
||||
m_Queue[inface(mface)].tp.pop_front();
|
||||
m_Queue[inface(mface)].pp.pop_front();
|
||||
}else
|
||||
{
|
||||
shared_ptr<Interest> interest = m_Queue[inface(mface)].qs.front();
|
||||
sendInterest(m_Queue[inface(mface)].ps.front(),FaceEndpoint(*getFaceTable().get(mface),0),*interest);
|
||||
m_Queue[inface(mface)].qs.pop_front();
|
||||
m_Queue[inface(mface)].ts.pop_front();
|
||||
m_Queue[inface(mface)].ps.pop_front();
|
||||
}
|
||||
}else
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MIRCCStrategy::calcRt(FaceId mface)
|
||||
{
|
||||
//每100ms自动重新计算Rt
|
||||
time::nanoseconds ttime(100000000);
|
||||
getScheduler().schedule(ttime, std::bind(&MIRCCStrategy::calcRt, this, mface));
|
||||
|
||||
long long ia,ib,Rp,Rs;
|
||||
double db;
|
||||
Rp = m_Rp_base[inface(mface)] + m_Rp_ex[inface(mface)];
|
||||
Rs = m_Rs_base[inface(mface)] + m_Rs_ex[inface(mface)];
|
||||
|
||||
NS_LOG_DEBUG("face:" << mface << "d:" << m_d[inface(mface)]);
|
||||
|
||||
NS_LOG_DEBUG("Rp: " << Rp << " Rs: " << Rs << " Yt: " << m_Yp[inface(mface)] << " C:" << m_linkC[inface(mface)]);
|
||||
//Rp计算过程
|
||||
ia = std::max(m_linkC[inface(mface)],m_Yp[inface(mface)]);
|
||||
|
||||
ib = std::max(Rp,1ll);
|
||||
double Np = std::max((double)ia / ib,1.0);
|
||||
|
||||
NS_LOG_DEBUG(" Np: " << Np);
|
||||
|
||||
double Bp;
|
||||
if (m_Yp[inface(mface)] >= m_Yp_old[inface(mface)])
|
||||
{
|
||||
ia = m_Yp[inface(mface)] - m_Yp_old[inface(mface)];
|
||||
|
||||
ib = std::max(m_Yp[inface(mface)],(uint64_t)1);
|
||||
|
||||
Bp = std::max(m_B,(double)ia / ib);
|
||||
}else
|
||||
{
|
||||
Bp = m_B;
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG(" Bp: " << Bp);
|
||||
|
||||
ia = m_miu * m_linkC[inface(mface)] - Bp * getQt(mface) / std::max((double)m_d[inface(mface)],(double)0.001);
|
||||
NS_LOG_DEBUG("Qt "<< getQt(mface) << " ia " << ia);
|
||||
db = std::max(Np,(double)1);
|
||||
long long Rp_base_n = std::min(std::max(ia / db,0.0),m_linkC[inface(mface)] / Np);
|
||||
NS_LOG_DEBUG(" Ppbn:" << Rp_base_n);
|
||||
m_Rp_base[inface(mface)] = m_a * m_Rp_base[inface(mface)] + (1 - m_a) * Rp_base_n;
|
||||
|
||||
NS_LOG_DEBUG(" Rpb: " << m_Rp_base[inface(mface)]);
|
||||
|
||||
ia = m_Yp[inface(mface)];
|
||||
|
||||
db = std::max(Np,(double)1);
|
||||
|
||||
long long Rp_ex_n = std::min(std::max((uint64_t)0,(uint64_t)(Rp - ia / db)),(uint64_t)(m_linkC[inface(mface)] - Rp_base_n));
|
||||
|
||||
m_Rp_ex[inface(mface)] = m_a * m_Rp_ex[inface(mface)] + (1 - m_a) * Rp_ex_n;
|
||||
NS_LOG_DEBUG(" Rpe: " << m_Rp_ex[inface(mface)]);
|
||||
NS_LOG_DEBUG(" !!Ppne:" << Rp_ex_n << " " << (m_linkC[inface(mface)] / Np - Rp_base_n));
|
||||
m_Yp_old[inface(mface)] = m_Yp[inface(mface)];
|
||||
|
||||
//Rs计算过程
|
||||
uint64_t Cs = std::max(m_linkC[inface(mface)] - m_Yp[inface(mface)] ,(uint64_t)0);
|
||||
|
||||
|
||||
NS_LOG_DEBUG(" Cs: " << Cs << " Ys" << m_Ys[inface(mface)]);
|
||||
|
||||
|
||||
//TODO: R(t-T) Rs? Rs+Rp?
|
||||
|
||||
double Ns = std::max((double)std::max(Cs,m_Ys[inface(mface)]) / std::max(Rp + Rs,1ll) ,1.0);
|
||||
|
||||
NS_LOG_DEBUG(" Ns: " << Ns);
|
||||
|
||||
ia = m_Ys[inface(mface)] - m_Ys_old[inface(mface)];
|
||||
ib = std::max(m_Ys[inface(mface)],(uint64_t)1);
|
||||
double Bs = std::max(m_B,(double)ia / ib);
|
||||
|
||||
|
||||
ia = m_miu * Cs - Bs * getQt(mface) / std::max(m_d[inface(mface)],(double)0.001);
|
||||
NS_LOG_DEBUG(" ia: " << ia);
|
||||
db = Ns;
|
||||
|
||||
uint64_t Rs_base_n = std::min((uint64_t)std::max(0.0,ia / db),uint64_t(Cs / Ns));
|
||||
m_Rs_base[inface(mface)] = m_a * m_Rs_base[inface(mface)] + (1 - m_a) * Rs_base_n;
|
||||
|
||||
NS_LOG_DEBUG(" Rsb: " << m_Rs_base[inface(mface)]);
|
||||
|
||||
|
||||
ia = m_Ys[inface(mface)];
|
||||
db = Ns;
|
||||
|
||||
|
||||
//TODO:: excess rate < 0 ? >= 0 ?
|
||||
uint64_t Rs_ex_n = std::min((uint64_t)std::max(0.0,Rs - ia / db),uint64_t(Cs - Rs_base_n));
|
||||
|
||||
m_Rs_ex[inface(mface)] = m_a * m_Rs_ex[inface(mface)] + (1 - m_a) * Rs_ex_n;
|
||||
|
||||
NS_LOG_DEBUG(" Rse: " << m_Rs_ex[inface(mface)]);
|
||||
|
||||
m_Ys_old[inface(mface)] = m_Ys[inface(mface)];
|
||||
|
||||
m_Yp[inface(mface)] = 0;
|
||||
m_Ys[inface(mface)] = 0;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MIRCCStrategy::getQt(FaceId mface)
|
||||
{
|
||||
|
||||
|
||||
//清除队列中过期兴趣包,避免造成干扰
|
||||
//refreshQueueInterest(mface);
|
||||
//返回兴趣包个数*兴趣包大小*数据包与兴趣包大小之比
|
||||
uint64_t time = 10;//保持Rt计算周期一致
|
||||
return (m_Queue[inface(mface)].qp.size() + m_Queue[inface(mface)].qs.size()) * DATA_SIZE * time;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::pushQueueInterest(FaceId mface,const shared_ptr<Interest>& interest,const shared_ptr<pit::Entry>& pitEntry)
|
||||
{
|
||||
//NS_LOG_DEBUG("MIRCC pushQueueInterest");
|
||||
uint64_t p = *(interest->getTag<lp::PTag>());
|
||||
//如果是第一类兴趣包
|
||||
if (p == 1)
|
||||
{
|
||||
//如果队列已经满了
|
||||
if (m_Queue[inface(mface)].qp.size() + m_Queue[inface(mface)].qs.size() >= MAX_QUEUE)
|
||||
{
|
||||
//如果存在第二类兴趣包可以删除
|
||||
if (m_Queue[inface(mface)].qs.size() > 0)
|
||||
{
|
||||
//删掉第二类兴趣包最后一个,把当前第一类兴趣包加入
|
||||
m_Queue[inface(mface)].qs.pop_back();
|
||||
m_Queue[inface(mface)].ts.pop_back();
|
||||
m_Queue[inface(mface)].ps.pop_back();
|
||||
m_Queue[inface(mface)].qp.push_back(interest);
|
||||
m_Queue[inface(mface)].tp.push_back(time::steady_clock::now());
|
||||
m_Queue[inface(mface)].pp.push_back(pitEntry);
|
||||
}else
|
||||
{
|
||||
//否则当前兴趣包丢失
|
||||
|
||||
//这里应该回传Nack,还没有写完
|
||||
}
|
||||
}else
|
||||
{
|
||||
//直接将当前兴趣包加入第一类兴趣包队列末尾
|
||||
m_Queue[inface(mface)].qp.push_back(interest);
|
||||
m_Queue[inface(mface)].tp.push_back(time::steady_clock::now());
|
||||
m_Queue[inface(mface)].pp.push_back(pitEntry);
|
||||
}
|
||||
}else
|
||||
{
|
||||
//如果队列已经满了
|
||||
if (m_Queue[inface(mface)].qp.size() + m_Queue[inface(mface)].qs.size() >= MAX_QUEUE)
|
||||
{
|
||||
//当前兴趣包丢失
|
||||
|
||||
//这里是否应该回传Nack不确定,需要回去看论文,第二类兴趣包处理方式似乎与第一类不同,还没有写完
|
||||
}else
|
||||
{
|
||||
//将但钱兴趣包加入第二类末尾
|
||||
m_Queue[inface(mface)].qs.push_back(interest);
|
||||
m_Queue[inface(mface)].ts.push_back(time::steady_clock::now());
|
||||
m_Queue[inface(mface)].ps.push_back(pitEntry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::afterReceiveInterest(const FaceEndpoint &ingress, const Interest &interest, const shared_ptr<pit::Entry> &pitEntry)
|
||||
{//目前在按照标识路径转发,采用MIRCC论文中的方法2
|
||||
//NS_LOG_DEBUG("MIRCC afterReceiveInterest");
|
||||
|
||||
if (hasPendingOutRecords(*pitEntry))
|
||||
{
|
||||
//已经有记录,等待即可。
|
||||
return;
|
||||
}
|
||||
|
||||
//避免巡回转发
|
||||
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
|
||||
fib::NextHopList outFaces = fibEntry.getNextHops();
|
||||
for (auto it = outFaces.begin();it != outFaces.end();it++)
|
||||
{
|
||||
if (it->getFace().getId() == ingress.face.getId())
|
||||
{
|
||||
outFaces.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outFaces.size() != 0)
|
||||
{
|
||||
//根据hash值选择端口
|
||||
uint64_t hashGuide = *interest.getTag<lp::PathidTag>();
|
||||
uint64_t Facenum = hashGuide % outFaces.size();
|
||||
hashGuide = hashGuide / outFaces.size();
|
||||
interest.setTag(make_shared<lp::PathidTag>(hashGuide));
|
||||
|
||||
Face& outFace = outFaces[Facenum].getFace();
|
||||
//更新Yt
|
||||
uint64_t p = *interest.getTag<lp::PTag>();
|
||||
uint64_t time = 10;//保持Rt计算周期一致
|
||||
if (p == 1)
|
||||
{
|
||||
m_Yp[inface(outFace.getId())] += DATA_SIZE * time;
|
||||
}else
|
||||
{
|
||||
m_Ys[inface(outFace.getId())] += DATA_SIZE * time;
|
||||
}
|
||||
|
||||
//放入对应端口队列进行排队
|
||||
this->pushQueueInterest(outFace.getId(), const_cast<Interest&>(interest).shared_from_this(), pitEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
//如果发现没有端口可以转发,则设置立马删除该条pit
|
||||
lp::NackHeader nackHeader;
|
||||
nackHeader.setReason(lp::NackReason::NO_ROUTE);
|
||||
this->sendNack(pitEntry, ingress, nackHeader);
|
||||
this->rejectPendingInterest(pitEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::afterReceiveNack(const FaceEndpoint &ingress, const lp::Nack &nack, const shared_ptr<pit::Entry> &pitEntry)
|
||||
{
|
||||
//NS_LOG_DEBUG("MIRCC afterReceiveNack");
|
||||
//nack无需处理
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry> &pitEntry, const FaceEndpoint &ingress, const Data &data)
|
||||
{
|
||||
//NS_LOG_DEBUG("MIRCC beforeSatisfyInterest");
|
||||
auto now = time::steady_clock::now();
|
||||
//目前计算中,只考虑没有过期的并成功收到数据包的兴趣包对RTT和ratio的影响.超时的数据包是否对RTT有影响?。
|
||||
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
|
||||
if (inRecord.getExpiry() > now)
|
||||
{
|
||||
if (inRecord.getFace().getId() == ingress.face.getId() && inRecord.getFace().getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
//计算收到数据包对RTT的影响。
|
||||
//RTT暂时为固定值50ms
|
||||
auto dura = now - inRecord.getLastRenewed();
|
||||
NS_LOG_DEBUG("RTT:" << dura.count());
|
||||
m_d[inface(ingress.face.getId())] = m_rtt_a * m_d[inface(ingress.face.getId())] + (1.0 - m_rtt_a) * ((double)dura.count() / 1000000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MIRCCStrategy::afterReceiveData(const shared_ptr<pit::Entry> &pitEntry, const FaceEndpoint &ingress, const Data &data)
|
||||
{
|
||||
|
||||
//NS_LOG_DEBUG("MIRCC afterReceiveData");
|
||||
|
||||
if (ingress.face.getId() >= 257)
|
||||
{
|
||||
//更新data的Pathid
|
||||
auto oldPathTag = data.getTag<lp::PathidTag>();
|
||||
uint64_t hashVal;
|
||||
if (oldPathTag != nullptr)
|
||||
{
|
||||
hashVal = *oldPathTag;
|
||||
}else
|
||||
{
|
||||
hashVal = 0;
|
||||
}
|
||||
hashVal = (hashVal * 10 + (ingress.face.getId() - 257));
|
||||
//给data设置新的hash值
|
||||
data.setTag(make_shared<lp::PathidTag>(hashVal));
|
||||
|
||||
auto FaceRateTag = data.getTag<lp::PTag>();
|
||||
if (FaceRateTag != nullptr)
|
||||
{
|
||||
m_linkC[inface(ingress.face.getId())] = *FaceRateTag;
|
||||
}else
|
||||
{
|
||||
//认定为app线路,速率设置为100MB/s
|
||||
m_linkC[inface(ingress.face.getId())] = 8 * 100 * 1000 * 1000;
|
||||
}
|
||||
|
||||
//修改Rt的值
|
||||
auto oldRpTag = data.getTag<lp::RpTag>();
|
||||
if (oldRpTag != nullptr)
|
||||
{
|
||||
uint64_t dataRp = *oldRpTag;
|
||||
if (dataRp > m_Rp_base[inface(ingress.face.getId())] + m_Rp_ex[inface(ingress.face.getId())])
|
||||
{
|
||||
data.setTag(make_shared<lp::RpTag>(m_Rp_base[inface(ingress.face.getId())] + m_Rp_ex[inface(ingress.face.getId())]));
|
||||
}
|
||||
}else
|
||||
{
|
||||
data.setTag(make_shared<lp::RpTag>(m_Rp_base[inface(ingress.face.getId())] + m_Rp_ex[inface(ingress.face.getId())]));
|
||||
}
|
||||
|
||||
//修改Rs的值
|
||||
auto oldRsTag = data.getTag<lp::RsTag>();
|
||||
if (oldRsTag != nullptr)
|
||||
{
|
||||
uint64_t dataRs =*oldRsTag;
|
||||
if (dataRs > m_Rs_base[inface(ingress.face.getId())] + m_Rs_ex[inface(ingress.face.getId())])
|
||||
{
|
||||
data.setTag(make_shared<lp::RsTag>(m_Rs_base[inface(ingress.face.getId())] + m_Rs_ex[inface(ingress.face.getId())]));
|
||||
}
|
||||
}else
|
||||
{
|
||||
data.setTag(make_shared<lp::RsTag>(m_Rs_base[inface(ingress.face.getId())] + m_Rs_ex[inface(ingress.face.getId())]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
beforeSatisfyInterest(pitEntry, ingress, data);
|
||||
sendDataToAll(pitEntry, ingress, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
|
||||
#include "face/face.hpp"
|
||||
#include "fw/strategy.hpp"
|
||||
#include "fw/algorithm.hpp"
|
||||
#include "fw/process-nack-traits.hpp"
|
||||
#include <unordered_map>
|
||||
#include <limits>
|
||||
#include <deque>
|
||||
#include "ndn-cxx/lp/tags.hpp"
|
||||
#include "common/global.hpp"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
class MIRCCQueue
|
||||
{
|
||||
public:
|
||||
std:: deque<shared_ptr<Interest>> qp,qs;
|
||||
//记录的是过期时间,非达到时间
|
||||
std:: deque<time::steady_clock::TimePoint> tp,ts;
|
||||
|
||||
std:: deque<shared_ptr<pit::Entry>> pp,ps;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
MIRCC 策略实现
|
||||
*/
|
||||
class MIRCCStrategy : public Strategy, public ProcessNackTraits<MIRCCStrategy>
|
||||
{
|
||||
public:
|
||||
explicit MIRCCStrategy(Forwarder &forwarder, const ndn::Name &name);
|
||||
|
||||
~MIRCCStrategy() override = default;
|
||||
|
||||
void
|
||||
afterReceiveInterest(const FaceEndpoint &ingress, const Interest &interest,const shared_ptr<pit::Entry> &pitEntry) override;
|
||||
|
||||
void
|
||||
afterReceiveNack(const FaceEndpoint &ingress, const lp::Nack &nack,const shared_ptr<pit::Entry> &pitEntry) override;
|
||||
|
||||
void
|
||||
beforeSatisfyInterest(const shared_ptr<pit::Entry> &pitEntry,const FaceEndpoint &ingress, const Data &data) override;
|
||||
|
||||
void
|
||||
afterReceiveData(const shared_ptr<pit::Entry> &pitEntry,const FaceEndpoint &ingress, const Data &data) override;
|
||||
|
||||
static const Name &
|
||||
getStrategyName();
|
||||
|
||||
protected:
|
||||
friend ProcessNackTraits<MIRCCStrategy>;
|
||||
|
||||
private:
|
||||
static const uint64_t MAX_FACE = 10;//单一节点最多支持10个外部端口,涉及到hash的计算
|
||||
const uint64_t DATA_SIZE = 8696;//固定数据包大小
|
||||
const uint64_t MAX_QUEUE = 10;//固定队列大小
|
||||
|
||||
const double m_B = 0.1;//公式B系数
|
||||
const double m_a = 0.5;//速率更新系数
|
||||
const double m_miu = 0.95;//链路利用率
|
||||
const double m_rtt_a = 0.7;//RTT更新系数
|
||||
|
||||
|
||||
uint64_t m_Rp_base[MAX_FACE];//Rp的base速率
|
||||
uint64_t m_Rp_ex[MAX_FACE];//Rp的ex速率
|
||||
uint64_t m_Rs_base[MAX_FACE];//Rs的base速率
|
||||
uint64_t m_Rs_ex[MAX_FACE];//Rs的ex速率
|
||||
uint64_t m_Yp[MAX_FACE];//本周期的Yp(t)
|
||||
uint64_t m_Yp_old[MAX_FACE];//上一个周期的Yp(t)
|
||||
uint64_t m_Ys[MAX_FACE];//本周起的Ys(t)
|
||||
uint64_t m_Ys_old[MAX_FACE];//上一个周期的Ys(t)
|
||||
uint64_t m_linkC[MAX_FACE];//每一个链路的带宽,单位为比特
|
||||
|
||||
double m_d[MAX_FACE];//维护每一个face的RTT 秒
|
||||
//注意,此处没有维护数据包/兴趣包,算法中采用固定的数据包大小
|
||||
|
||||
MIRCCQueue m_Queue[MAX_FACE];//用于出口排队转发兴趣
|
||||
|
||||
//发送mface端口1个正在排队的兴趣包,并设置下一次发送时间
|
||||
void
|
||||
sendQueueInterest(FaceId mface);
|
||||
|
||||
//将兴趣包放入mface端口的队列
|
||||
void
|
||||
pushQueueInterest(FaceId mface, const shared_ptr<Interest>& interest,const shared_ptr<pit::Entry>& pitEntry);
|
||||
|
||||
//计算并返回mface端口的q(t)
|
||||
uint64_t
|
||||
getQt(FaceId mface);
|
||||
|
||||
//对于mface端口周期性计算Rt
|
||||
void
|
||||
calcRt(FaceId mface);
|
||||
|
||||
//拖延1ns后进行初始化,避免发现端口失败
|
||||
void
|
||||
mirccinit();
|
||||
|
||||
//将端口号映射至从0开始
|
||||
uint64_t
|
||||
inface(FaceId mface)
|
||||
{
|
||||
return mface - 257;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+1551
-25319
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,117 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2011-2015 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
|
||||
* contributors.
|
||||
*
|
||||
* ndnSIM is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndnSIM 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
|
||||
* ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
// ndn-congestion-topo-plugin.cpp
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/ndnSIM-module.h"
|
||||
#include "../extensions/mircc-strategy.hpp"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* This scenario simulates a grid topology (using topology reader module)
|
||||
*
|
||||
* /------\ /------\
|
||||
* | Src1 |<--+ +-->| Dst1 |
|
||||
* \------/ \ / \------/
|
||||
* \ /
|
||||
* +-->/------\ "bottleneck" /------\<-+
|
||||
* | Rtr1 |<===============>| Rtr2 |
|
||||
* +-->\------/ \------/<-+
|
||||
*
|
||||
* To run scenario and see what is happening, use the following command:
|
||||
*
|
||||
* NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-congestion-topo-plugin
|
||||
*/
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
CommandLine cmd;
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
AnnotatedTopologyReader topologyReader("", 25);
|
||||
topologyReader.SetFileName("topologies/topo-4-node.txt");
|
||||
topologyReader.Read();
|
||||
|
||||
// Install NDN stack on all nodes
|
||||
ndn::StackHelper ndnHelper;
|
||||
ndnHelper.setPolicy("nfd::cs::lru");
|
||||
ndnHelper.setCsSize(10000);
|
||||
ndnHelper.InstallAll();
|
||||
|
||||
// Choosing forwarding strategy
|
||||
ndn::StrategyChoiceHelper::InstallAll<nfd::fw::MIRCCStrategy>("/");
|
||||
//ndn::StrategyChoiceHelper::InstallAll<nfd::fw::SelfLearningStrategy>("/prefix");
|
||||
//ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route-strategy");
|
||||
|
||||
// Installing global routing interface on all nodes
|
||||
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
|
||||
ndnGlobalRoutingHelper.InstallAll();
|
||||
|
||||
// Getting containers for the consumer/producer
|
||||
Ptr<Node> consumer1 = Names::Find<Node>("Src1");
|
||||
|
||||
Ptr<Node> producer1 = Names::Find<Node>("Dst1");
|
||||
|
||||
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerMIRCC");
|
||||
//ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
|
||||
consumerHelper.SetAttribute("MaxSeq", StringValue("10000000")); // 100 interests a second
|
||||
consumerHelper.SetAttribute("start_ms", StringValue("1000")); // 100 interests a second
|
||||
|
||||
|
||||
// on the first consumer node install a Consumer application
|
||||
// that will express interests in /dst1 namespace
|
||||
consumerHelper.SetPrefix("/dst1");
|
||||
consumerHelper.Install(consumer1);
|
||||
|
||||
ndn::AppHelper producerHelper("ns3::ndn::Producer");
|
||||
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
|
||||
|
||||
// Register /dst1 prefix with global routing controller and
|
||||
// install producer that will satisfy Interests in /dst1 namespace
|
||||
ndnGlobalRoutingHelper.AddOrigins("/dst1", producer1);
|
||||
producerHelper.SetPrefix("/dst1");
|
||||
producerHelper.Install(producer1);
|
||||
|
||||
// Calculate and install FIBs
|
||||
ndn::GlobalRoutingHelper::CalculateRoutes();
|
||||
|
||||
Simulator::Stop(Seconds(3.0));
|
||||
|
||||
ndn::L3RateTracer::InstallAll("out1.txt",Seconds(0.5));
|
||||
ndn::AppDelayTracer::InstallAll("out2.txt");
|
||||
L2RateTracer::InstallAll("out3",Seconds(1));
|
||||
|
||||
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return ns3::main(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2011-2015 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
|
||||
* contributors.
|
||||
*
|
||||
* ndnSIM is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndnSIM 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
|
||||
* ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
// ndn-congestion-topo-plugin.cpp
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/ndnSIM-module.h"
|
||||
#include "../extensions/mircc-strategy.hpp"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* This scenario simulates a grid topology (using topology reader module)
|
||||
*
|
||||
* /------\ /------\
|
||||
* | Src1 |<--+ +-->| Dst1 |
|
||||
* \------/ \ / \------/
|
||||
* \ /
|
||||
* +-->/------\ "bottleneck" /------\<-+
|
||||
* | Rtr1 |<===============>| Rtr2 |
|
||||
* +-->\------/ \------/<-+
|
||||
*
|
||||
* To run scenario and see what is happening, use the following command:
|
||||
*
|
||||
* NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-congestion-topo-plugin
|
||||
*/
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
CommandLine cmd;
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
AnnotatedTopologyReader topologyReader("", 25);
|
||||
topologyReader.SetFileName("topologies/topo-4-node.txt");
|
||||
topologyReader.Read();
|
||||
|
||||
// Install NDN stack on all nodes
|
||||
ndn::StackHelper ndnHelper;
|
||||
ndnHelper.setPolicy("nfd::cs::lru");
|
||||
ndnHelper.setCsSize(1);
|
||||
ndnHelper.InstallAll();
|
||||
|
||||
// Choosing forwarding strategy
|
||||
ndn::StrategyChoiceHelper::InstallAll<nfd::fw::MIRCCStrategy>("/");
|
||||
//ndn::StrategyChoiceHelper::InstallAll<nfd::fw::SelfLearningStrategy>("/prefix");
|
||||
//ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route-strategy");
|
||||
|
||||
// Installing global routing interface on all nodes
|
||||
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
|
||||
ndnGlobalRoutingHelper.InstallAll();
|
||||
|
||||
// Getting containers for the consumer/producer
|
||||
Ptr<Node> consumer1 = Names::Find<Node>("Src1");
|
||||
|
||||
Ptr<Node> producer1 = Names::Find<Node>("Dst1");
|
||||
|
||||
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerMIRCC");
|
||||
//ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
|
||||
consumerHelper.SetAttribute("MaxSeq", StringValue("10000000")); // 100 interests a second
|
||||
consumerHelper.SetAttribute("start_ms", StringValue("1")); // 100 interests a second
|
||||
consumerHelper.SetPrefix("/dst1");
|
||||
consumerHelper.Install(consumer1);
|
||||
|
||||
|
||||
ndn::AppHelper consumerHelper2("ns3::ndn::ConsumerMIRCC");
|
||||
consumerHelper2.SetAttribute("MaxSeq", StringValue("10000000")); // 100 interests a second
|
||||
consumerHelper2.SetAttribute("start_ms", StringValue("3000")); // 100 interests a second
|
||||
consumerHelper2.SetPrefix("/dst1");
|
||||
consumerHelper2.Install(consumer1);
|
||||
consumerHelper2.Install(consumer1);
|
||||
consumerHelper2.Install(consumer1);
|
||||
/*
|
||||
ndn::AppHelper consumerHelper3("ns3::ndn::ConsumerMIRCC");
|
||||
consumerHelper3.SetAttribute("MaxSeq", StringValue("10000000")); // 100 interests a second
|
||||
consumerHelper3.SetAttribute("start_ms", StringValue("1500")); // 100 interests a second
|
||||
consumerHelper3.SetPrefix("/dst3");
|
||||
consumerHelper3.Install(consumer1);
|
||||
|
||||
ndn::AppHelper consumerHelper4("ns3::ndn::ConsumerMIRCC");
|
||||
consumerHelper4.SetAttribute("MaxSeq", StringValue("10000000")); // 100 interests a second
|
||||
consumerHelper4.SetAttribute("start_ms", StringValue("1500")); // 100 interests a second
|
||||
consumerHelper4.SetPrefix("/dst4");
|
||||
consumerHelper4.Install(consumer1);*/
|
||||
|
||||
|
||||
|
||||
|
||||
ndn::AppHelper producerHelper("ns3::ndn::Producer");
|
||||
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
|
||||
ndnGlobalRoutingHelper.AddOrigins("/dst1", producer1);
|
||||
producerHelper.SetPrefix("/dst1");
|
||||
producerHelper.Install(producer1);
|
||||
/*
|
||||
ndn::AppHelper producerHelper2("ns3::ndn::Producer");
|
||||
producerHelper2.SetAttribute("PayloadSize", StringValue("1024"));
|
||||
ndnGlobalRoutingHelper.AddOrigins("/dst2", producer1);
|
||||
producerHelper2.SetPrefix("/dst2");
|
||||
producerHelper2.Install(producer1);
|
||||
|
||||
ndn::AppHelper producerHelper3("ns3::ndn::Producer");
|
||||
producerHelper3.SetAttribute("PayloadSize", StringValue("1024"));
|
||||
ndnGlobalRoutingHelper.AddOrigins("/dst3", producer1);
|
||||
producerHelper3.SetPrefix("/dst3");
|
||||
producerHelper3.Install(producer1);
|
||||
|
||||
ndn::AppHelper producerHelper4("ns3::ndn::Producer");
|
||||
producerHelper4.SetAttribute("PayloadSize", StringValue("1024"));
|
||||
ndnGlobalRoutingHelper.AddOrigins("/dst4", producer1);
|
||||
producerHelper4.SetPrefix("/dst4");
|
||||
producerHelper4.Install(producer1);
|
||||
*/
|
||||
// ndnGlobalRoutingHelper.AddOrigins("/dst2", producer1);
|
||||
//producerHelper.SetPrefix("/dst2");
|
||||
//producerHelper.Install(producer1);
|
||||
|
||||
//ndnGlobalRoutingHelper.AddOrigins("/dst3", producer1);
|
||||
//producerHelper.SetPrefix("/dst3");
|
||||
//producerHelper.Install(producer1);
|
||||
|
||||
//ndnGlobalRoutingHelper.AddOrigins("/dst4", producer1);
|
||||
//producerHelper.SetPrefix("/dst4");
|
||||
//producerHelper.Install(producer1);
|
||||
// Calculate and install FIBs
|
||||
ndn::GlobalRoutingHelper::CalculateRoutes();
|
||||
|
||||
Simulator::Stop(Seconds(10));
|
||||
|
||||
ndn::L3RateTracer::InstallAll("out1.txt",Seconds(0.1));
|
||||
ndn::AppDelayTracer::InstallAll("out2.txt");
|
||||
L2RateTracer::InstallAll("out3",Seconds(1));
|
||||
|
||||
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return ns3::main(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2011-2015 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
|
||||
* contributors.
|
||||
*
|
||||
* ndnSIM is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndnSIM 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
|
||||
* ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
// ndn-congestion-topo-plugin.cpp
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/ndnSIM-module.h"
|
||||
#include "../extensions/mircc-strategy.hpp"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
CommandLine cmd;
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
AnnotatedTopologyReader topologyReader("", 25);
|
||||
topologyReader.SetFileName("topologies/Slingshot.txt");
|
||||
topologyReader.Read();
|
||||
|
||||
// Install NDN stack on all nodes
|
||||
ndn::StackHelper ndnHelper;
|
||||
ndnHelper.setPolicy("nfd::cs::lru");
|
||||
ndnHelper.setCsSize(1);
|
||||
ndnHelper.InstallAll();
|
||||
|
||||
// Choosing forwarding strategy
|
||||
ndn::StrategyChoiceHelper::InstallAll<nfd::fw::MIRCCStrategy>("/");
|
||||
//ndn::StrategyChoiceHelper::InstallAll<nfd::fw::SelfLearningStrategy>("/prefix");
|
||||
//ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route-strategy");
|
||||
|
||||
// Installing global routing interface on all nodes
|
||||
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
|
||||
ndnGlobalRoutingHelper.InstallAll();
|
||||
|
||||
// Getting containers for the consumer/producer
|
||||
Ptr<Node> consumer1 = Names::Find<Node>("Src1");
|
||||
|
||||
Ptr<Node> producer1 = Names::Find<Node>("Dst1");
|
||||
Ptr<Node> producer2 = Names::Find<Node>("Dst2");
|
||||
|
||||
|
||||
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerMIRCC");
|
||||
consumerHelper.SetAttribute("MaxSeq", StringValue("1000000000")); // 100 interests a second
|
||||
consumerHelper.SetPrefix("/d1");
|
||||
consumerHelper.SetAttribute("logtms",StringValue("100"));
|
||||
consumerHelper.SetAttribute("appid",StringValue("1"));
|
||||
consumerHelper.SetAttribute("start_ms",StringValue("0"));
|
||||
consumerHelper.SetAttribute("end_ms",StringValue("10000"));
|
||||
consumerHelper.Install(consumer1);
|
||||
|
||||
|
||||
consumerHelper.SetPrefix("/d2");
|
||||
consumerHelper.SetAttribute("appid",StringValue("2"));
|
||||
consumerHelper.SetAttribute("start_ms",StringValue("1500"));
|
||||
consumerHelper.SetAttribute("end_ms",StringValue("5000"));
|
||||
consumerHelper.SetAttribute("greedy_ms",StringValue("3000"));
|
||||
consumerHelper.SetAttribute("greedy_rate",StringValue("10000000"));
|
||||
consumerHelper.Install(consumer1);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ndn::AppHelper producerHelper("ns3::ndn::Producer");
|
||||
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
|
||||
producerHelper.SetPrefix("/d1");
|
||||
producerHelper.Install(producer1);
|
||||
producerHelper.Install(producer2);
|
||||
producerHelper.SetPrefix("/d2");
|
||||
producerHelper.Install(producer2);
|
||||
|
||||
ndnGlobalRoutingHelper.AddOrigins("/d1", producer1);
|
||||
ndnGlobalRoutingHelper.AddOrigins("/d1", producer2);
|
||||
ndnGlobalRoutingHelper.AddOrigins("/d2", producer2);
|
||||
|
||||
ndn::GlobalRoutingHelper::CalculateRoutes();
|
||||
|
||||
Simulator::Stop(Seconds(5));
|
||||
|
||||
ndn::L3RateTracer::InstallAll("out1.txt",Seconds(0.1));
|
||||
ndn::AppDelayTracer::InstallAll("out2.txt");
|
||||
L2RateTracer::InstallAll("out3",Seconds(1));
|
||||
|
||||
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return ns3::main(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
Src1 NA 2 1
|
||||
Rtr1 NA 2 2
|
||||
Dst1 NA 3 3
|
||||
Dst2 NA 1 3
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
Src1 Rtr1 7.5Mbps 1 10ms 20
|
||||
Rtr1 Dst1 6Mbps 1 10ms 20
|
||||
Rtr1 Dst2 4.5Mbps 1 10ms 20
|
||||
@@ -0,0 +1,35 @@
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
R1 NA 5 3
|
||||
R2 NA 5 5
|
||||
R4 NA 5 7
|
||||
R6 NA 5 9
|
||||
C1 NA 7 1
|
||||
C2 NA 5 1
|
||||
C3 NA 3 1
|
||||
P1 NA 8 11
|
||||
P2 NA 6 11
|
||||
P3 NA 4 11
|
||||
P4 NA 2 11
|
||||
R3 NA 7 8
|
||||
R5 NA 3 8
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
C1 R1 100Mbps 1 10ms 20
|
||||
C2 R1 100Mbps 1 10ms 20
|
||||
C3 R1 100Mbps 1 10ms 20
|
||||
R6 P1 100Mbps 1 10ms 20
|
||||
R6 P2 100Mbps 1 10ms 20
|
||||
R6 P3 100Mbps 1 10ms 20
|
||||
R6 P4 100Mbps 1 10ms 20
|
||||
R1 R2 8Mbps 1 10ms 20
|
||||
R2 R3 1Mbps 1 10ms 20
|
||||
R4 R3 2Mbps 1 5ms 20
|
||||
R3 R6 3Mbps 1 10ms 20
|
||||
R4 R5 3Mbps 1 5ms 20
|
||||
R2 R4 5Mbps 1 5ms 20
|
||||
R2 R5 4Mbps 1 10ms 20
|
||||
R5 R6 7Mbps 1 10ms 20
|
||||
@@ -0,0 +1,24 @@
|
||||
# topo-4-node.txt
|
||||
# /------\0 /------\3
|
||||
# | Src1 |<--+ +-->| Dst1 |
|
||||
# \------/ \ / \------/
|
||||
# \ /
|
||||
# +-->/------\1 "bottleneck" /------\2<-+
|
||||
# | Rtr1 |<===============>| Rtr2 |
|
||||
# \------/ \------/
|
||||
|
||||
|
||||
router
|
||||
|
||||
# node comment yPos xPos
|
||||
Src1 NA 1 3
|
||||
Rtr1 NA 2 5
|
||||
Rtr2 NA 2 7
|
||||
Dst1 NA 1 9
|
||||
|
||||
link
|
||||
|
||||
# srcNode dstNode bandwidth metric delay queue
|
||||
Src1 Rtr1 1Mbps 1 10ms 20
|
||||
Rtr1 Rtr2 1Mbps 1 10ms 20
|
||||
Dst1 Rtr2 1Mbps 1 10ms 20
|
||||
Reference in new issue
Block a user