lp: add CongestionMark field and tag
refs #3797
Change-Id: I6ac6663c874abde1df2102af81fc03567ad87029
diff --git a/src/detail/face-impl.hpp b/src/detail/face-impl.hpp
index 998ab34..9ce4a69 100644
--- a/src/detail/face-impl.hpp
+++ b/src/detail/face-impl.hpp
@@ -93,6 +93,11 @@
packet.add<lp::NextHopFaceIdField>(*nextHopFaceIdTag);
}
+ shared_ptr<lp::CongestionMarkTag> congestionMarkTag = interest->getTag<lp::CongestionMarkTag>();
+ if (congestionMarkTag != nullptr) {
+ packet.add<lp::CongestionMarkField>(*congestionMarkTag);
+ }
+
packet.add<lp::FragmentField>(std::make_pair(interest->wireEncode().begin(),
interest->wireEncode().end()));
diff --git a/src/face.cpp b/src/face.cpp
index d20f57c..430f65e 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -240,10 +240,22 @@
{
Block wire = data.wireEncode();
+ lp::Packet packet;
+ bool hasLpFields = false;
+
shared_ptr<lp::CachePolicyTag> cachePolicyTag = data.getTag<lp::CachePolicyTag>();
if (cachePolicyTag != nullptr) {
- lp::Packet packet;
packet.add<lp::CachePolicyField>(*cachePolicyTag);
+ hasLpFields = true;
+ }
+
+ shared_ptr<lp::CongestionMarkTag> congestionMarkTag = data.getTag<lp::CongestionMarkTag>();
+ if (congestionMarkTag != nullptr) {
+ packet.add<lp::CongestionMarkField>(*congestionMarkTag);
+ hasLpFields = true;
+ }
+
+ if (hasLpFields) {
packet.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
wire = packet.wireEncode();
}
@@ -264,6 +276,11 @@
const Block& interestWire = nack.getInterest().wireEncode();
packet.add<lp::FragmentField>(std::make_pair(interestWire.begin(), interestWire.end()));
+ shared_ptr<lp::CongestionMarkTag> congestionMarkTag = nack.getTag<lp::CongestionMarkTag>();
+ if (congestionMarkTag != nullptr) {
+ packet.add<lp::CongestionMarkField>(*congestionMarkTag);
+ }
+
Block wire = packet.wireEncode();
if (wire.size() > MAX_NDN_PACKET_SIZE)
@@ -500,13 +517,17 @@
/**
* @brief extract local fields from NDNLPv2 packet and tag onto a network layer packet
*/
-template<typename NETPKT>
+template<typename NetPkt>
static void
-extractLpLocalFields(NETPKT& netPacket, const lp::Packet& lpPacket)
+extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
{
if (lpPacket.has<lp::IncomingFaceIdField>()) {
netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
}
+
+ if (lpPacket.has<lp::CongestionMarkField>()) {
+ netPacket.setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
+ }
}
void
diff --git a/src/lp/fields.hpp b/src/lp/fields.hpp
index ff9db28..7d898d0 100644
--- a/src/lp/fields.hpp
+++ b/src/lp/fields.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -68,6 +68,11 @@
tlv::IncomingFaceId> IncomingFaceIdField;
BOOST_CONCEPT_ASSERT((Field<IncomingFaceIdField>));
+typedef detail::FieldDecl<field_location_tags::Header,
+ uint64_t,
+ tlv::CongestionMark> CongestionMarkField;
+BOOST_CONCEPT_ASSERT((Field<CongestionMarkField>));
+
/**
* The value of the wire encoded field is the data between the provided iterators. During
* encoding, the data is copied from the Buffer into the wire buffer.
@@ -88,7 +93,8 @@
NackField,
NextHopFaceIdField,
CachePolicyField,
- IncomingFaceIdField
+ IncomingFaceIdField,
+ CongestionMarkField
> FieldSet;
} // namespace lp
diff --git a/src/lp/tags.hpp b/src/lp/tags.hpp
index c7fcefe..5e2b3d6 100644
--- a/src/lp/tags.hpp
+++ b/src/lp/tags.hpp
@@ -49,6 +49,13 @@
*/
typedef SimpleTag<CachePolicy, 12> CachePolicyTag;
+/** \class CongestionMarkTag
+ * \brief a packet tag for CongestionMark field
+ *
+ * This tag can be attached to Interest, Data, Nack.
+ */
+typedef SimpleTag<uint64_t, 13> CongestionMarkTag;
+
} // namespace lp
} // namespace ndn
diff --git a/src/lp/tlv.hpp b/src/lp/tlv.hpp
index 3231660..e7a5cca 100644
--- a/src/lp/tlv.hpp
+++ b/src/lp/tlv.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -40,7 +40,8 @@
NextHopFaceId = 816,
CachePolicy = 820,
CachePolicyType = 821,
- IncomingFaceId = 817
+ IncomingFaceId = 817,
+ CongestionMark = 832
};
enum {
diff --git a/src/util/dummy-client-face.cpp b/src/util/dummy-client-face.cpp
index 43efff9..911d3bb 100644
--- a/src/util/dummy-client-face.cpp
+++ b/src/util/dummy-client-face.cpp
@@ -137,12 +137,18 @@
if (lpPacket.has<lp::NextHopFaceIdField>()) {
nack->setTag(make_shared<lp::NextHopFaceIdTag>(lpPacket.get<lp::NextHopFaceIdField>()));
}
+ if (lpPacket.has<lp::CongestionMarkField>()) {
+ nack->setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
+ }
onSendNack(*nack);
}
else {
if (lpPacket.has<lp::NextHopFaceIdField>()) {
interest->setTag(make_shared<lp::NextHopFaceIdTag>(lpPacket.get<lp::NextHopFaceIdField>()));
}
+ if (lpPacket.has<lp::CongestionMarkField>()) {
+ interest->setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
+ }
onSendInterest(*interest);
}
}
@@ -152,6 +158,9 @@
if (lpPacket.has<lp::CachePolicyField>()) {
data->setTag(make_shared<lp::CachePolicyTag>(lpPacket.get<lp::CachePolicyField>()));
}
+ if (lpPacket.has<lp::CongestionMarkField>()) {
+ data->setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
+ }
onSendData(*data);
}
@@ -208,23 +217,26 @@
});
}
+template<typename Packet, typename Field, typename Tag>
+static void
+addFieldFromTag(lp::Packet& lpPacket, const Packet& packet)
+{
+ shared_ptr<Tag> tag = static_cast<const TagHost&>(packet).getTag<Tag>();
+ if (tag != nullptr) {
+ lpPacket.add<Field>(*tag);
+ }
+}
+
template<typename Packet>
void
DummyClientFace::receive(const Packet& packet)
{
lp::Packet lpPacket(packet.wireEncode());
- shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag =
- static_cast<const TagHost&>(packet).getTag<lp::IncomingFaceIdTag>();
- if (incomingFaceIdTag != nullptr) {
- lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
- }
+ addFieldFromTag<Packet, lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, packet);
+ addFieldFromTag<Packet, lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, packet);
+ addFieldFromTag<Packet, lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, packet);
- shared_ptr<lp::NextHopFaceIdTag> nextHopFaceIdTag =
- static_cast<const TagHost&>(packet).getTag<lp::NextHopFaceIdTag>();
- if (nextHopFaceIdTag != nullptr) {
- lpPacket.add<lp::NextHopFaceIdField>(*nextHopFaceIdTag);
- }
static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
}
@@ -243,10 +255,8 @@
Block interest = nack.getInterest().wireEncode();
lpPacket.add<lp::FragmentField>(make_pair(interest.begin(), interest.end()));
- shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = nack.getTag<lp::IncomingFaceIdTag>();
- if (incomingFaceIdTag != nullptr) {
- lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
- }
+ addFieldFromTag<lp::Nack, lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
+ addFieldFromTag<lp::Nack, lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
}
diff --git a/tests/unit-tests/face.t.cpp b/tests/unit-tests/face.t.cpp
index dfaefd5..c25681b 100644
--- a/tests/unit-tests/face.t.cpp
+++ b/tests/unit-tests/face.t.cpp
@@ -316,12 +316,15 @@
lp::CachePolicy cachePolicy;
cachePolicy.setPolicy(lp::CachePolicyType::NO_CACHE);
data.setTag(make_shared<lp::CachePolicyTag>(cachePolicy));
+ data.setTag(make_shared<lp::CongestionMarkTag>(1));
face.put(data);
advanceClocks(time::milliseconds(10));
BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
BOOST_CHECK(face.sentData[0].getTag<lp::CachePolicyTag>() == nullptr);
+ BOOST_CHECK(face.sentData[0].getTag<lp::CongestionMarkTag>() == nullptr);
BOOST_CHECK(face.sentData[1].getTag<lp::CachePolicyTag>() != nullptr);
+ BOOST_CHECK(face.sentData[1].getTag<lp::CongestionMarkTag>() != nullptr);
}
BOOST_AUTO_TEST_CASE(PutNack)
@@ -332,6 +335,15 @@
advanceClocks(time::milliseconds(10));
BOOST_CHECK_EQUAL(face.sentNacks.size(), 1);
+
+ auto nack = makeNack(Interest("/another/prefix", time::milliseconds(50)), lp::NackReason::NO_ROUTE);
+ nack.setTag(make_shared<lp::CongestionMarkTag>(1));
+ face.put(nack);
+
+ advanceClocks(time::milliseconds(10));
+ BOOST_REQUIRE_EQUAL(face.sentNacks.size(), 2);
+ BOOST_CHECK(face.sentNacks[0].getTag<lp::CongestionMarkTag>() == nullptr);
+ BOOST_CHECK(face.sentNacks[1].getTag<lp::CongestionMarkTag>() != nullptr);
}
BOOST_AUTO_TEST_CASE(SetUnsetInterestFilter)