Feature #4849
closedEndpointId in forwarding and Strategy API
80%
Description
In Forwarder
class and Strategy
base class APIs, add inEndpointId
argument alongside inFace
, and add outEndpointId
argument alongside outFace
.
Updated by Junxiao Shi almost 6 years ago
- Blocks Feature #4281: Develop self-learning for broadcast and ad hoc wireless faces added
Updated by Junxiao Shi almost 6 years ago
- Blocked by Feature #4842: EndpointId in PIT in-record and out-record added
Updated by Md Ashiqur Rahman almost 6 years ago
Should the fw::UnsolicitedDataPolicy
and fw::UnsolicitedDataDecision
also have this column?
Updated by Md Ashiqur Rahman almost 6 years ago
Oh, wait, this is appearing to be a little vague in the issue description, so in the following code of the Forwarder class, we have:
Forwarder::Forwarder()
: m_unsolicitedDataPolicy(new fw::DefaultUnsolicitedDataPolicy())
, m_fib(m_nameTree)
, m_pit(m_nameTree)
, m_measurements(m_nameTree)
, m_strategyChoice(*this)
{
m_faceTable.afterAdd.connect([this] (Face& face) {
face.afterReceiveInterest.connect(
[this, &face] (const Interest& interest) {
this->startProcessInterest(face, interest);
});
face.afterReceiveData.connect(
[this, &face] (const Data& data) {
this->startProcessData(face, data);
});
face.afterReceiveNack.connect(
[this, &face] (const lp::Nack& nack) {
this->startProcessNack(face, nack);
});
face.onDroppedInterest.connect(
[this, &face] (const Interest& interest) {
this->onDroppedInterest(face, interest);
});
});
m_faceTable.beforeRemove.connect([this] (Face& face) {
cleanupOnFaceRemoval(m_nameTree, m_fib, m_pit, face);
});
m_strategyChoice.setDefaultStrategy(getDefaultStrategyName());
}
Shouldn't the afterReceiveInterest, the related startProcessInterest and so on also receive the endpointId filed? or will the endpointId
be processed after the startProcess...
methods are called?
I was under the impression that the endpointId
would be processed by lp
and then given to the forwarder
(maybe I misunderstood from the NFD call discussion). Or is it going to be processed by forwarder
directly and then given to the strategy?
Updated by Junxiao Shi almost 6 years ago
- Related to Feature #4843: EndpointId in LinkService added
Updated by Junxiao Shi almost 6 years ago
- Subject changed from EndpointId in Strategy API to EndpointId in forwarding and Strategy API
I was under the impression that the endpointId would be processed by lp and then given to the forwarder
Correct. #4843 should change LinkService.
Updated by Md Ashiqur Rahman almost 6 years ago
In the Strategy
class, should the Strategy::sendDataToAll
method receive the endpointId
at all?
void
Strategy::sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data,
const Face& outFace, uint64_t outEndpointId)
{
BOOST_ASSERT(pitEntry->getInterest().matchesData(data));
// delete the PIT entry's in-record based on outFace and outEndpointId,
// since Data is sent to outFace with outEndpointId from which the Interest was received
pitEntry->deleteInRecord(outFace, outEndpointId);
m_forwarder.onOutgoingData(data, *const_pointer_cast<Face>(outFace.shared_from_this()), outEndpointId);
}
void
Strategy::sendDataToAll(const shared_ptr<pit::Entry>& pitEntry,
const Face& inFace, uint64_t inEndpointId, const Data& data)
{
std::set<Face*> pendingDownstreams;
auto now = time::steady_clock::now();
// remember pending downstreams
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
if (inRecord.getExpiry() > now) {
if (inRecord.getFace().getId() == inFace.getId() &&
inRecord.getFace().getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
continue;
}
pendingDownstreams.insert(&inRecord.getFace());
}
}
for (const Face* pendingDownstream : pendingDownstreams) {
this->sendData(pitEntry, data, *pendingDownstream, 0);
}
}
The pendingDownstream
set built from the Face
class does not contain the endpointId
column. then in case of this sendDataToAll
method, how is the sendData
going to know which outEndpontId
-s will receive the Data packet?
Or should I just set the value to 0
for now and worry about this in issue #4281?
Updated by Junxiao Shi almost 6 years ago
The pendingDownstream set built from the Face class does not contain the endpointId column.
pendingDownstreams
should be keyed by FaceId+EndpointId, not just FaceId or Face pointer.
Updated by Md Ashiqur Rahman almost 6 years ago
The pendingDownstream set built from the Face class does not contain the endpointId column.
pendingDownstreams
should be keyed by FaceId+EndpointId, not just FaceId or Face pointer.
Do you mean something like this:
std::set< std::pair<Face*,uint64_t> > pendingDownstreams;
...
...
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
if (inRecord.getExpiry() > now) {
if (inRecord.getFace().getId() == inFace.getId()
inRecord.getFace().getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
continue;
}
pendingDownstreams.insert(std::make_pair(&inRecord.getFace(), &inRecord.getEndpointId()));
}
}
...
...
for (std::pair<const Face*, uint64_t> pendingDownstream : pendingDownstreams) {
this->sendData(pitEntry, data, *pendingDownstream.first, pendingDownstream.second);
}
I'm not understanding the purpose of the inEndpointId
argument in the Strategy::sendDataToAll
method.
If I do this:
if (inRecord.getFace().getId() == inFace.getId() && inRecord.getEndpointId() == inEndpointId &&
inRecord.getFace().getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
continue;
}
then am I not just picking up only one next hop to send back the Data? Whereas I can have multiple next-hops through multiple NIC's?
Updated by Junxiao Shi almost 6 years ago
The expected behavior of sendDataToAll is sending Data to every FaceId+EndpointId combination among PIT downstream records, except inFace+inEndpointId; for ad-hoc wireless face when EndpointId is zero, the Data can be sent.
You can decide on internal implementation as long as this behavior is achieved.
Updated by Md Ashiqur Rahman almost 6 years ago
The modifications affected by this issue appears to be propagated over many strategies too.
Should I just add the desired parameter in the function for now and later focus on the actual values to be passed for the function calls? i.e. set the parameter value passed for endpointId
to 0
for now.
Updated by Junxiao Shi almost 6 years ago
Should I just add the desired parameter in the function for now and later focus on the actual values to be passed for the function calls? i.e. set the parameter value passed for
endpointId
to0
for now.
Yes, that's fine for individual strategies. In strategy class Doxygen, indicate this limitation: \note This strategy is not EndpointId-aware.
.
Updated by Junxiao Shi over 5 years ago
- Status changed from New to In Progress
- % Done changed from 90 to 50
Change 5270 adds EndpointId to the strategy API but did not fully implement it because face system does not fully implement sending and receiving packets with EndpointId. This limitation is to be addressed in another commit under this issue.
In Strategy::sendDataToAll
: Even on a wireless ad hoc link, a node shouldn't send Data back to a non-zero endpointId because that would unicast the Data back to where it comes from.
NFD Developer Guide strategy API section must be updated accordingly.
Updated by Md Ashiqur Rahman over 5 years ago
Junxiao Shi wrote:
Change 5270 adds EndpointId to the strategy API but did not fully implement it because face system does not fully implement sending and receiving packets with EndpointId. This limitation is to be addressed in another commit under this issue.
InStrategy::sendDataToAll
: Even on a wireless ad hoc link, a node shouldn't send Data back to a non-zero endpointId because that would unicast the Data back to where it comes from.
Question: Do we consider an EndpointID=0
as a broadcast address and other values as unicast? or a nullptr
as broadcast address and others as unicast?
NFD Developer Guide strategy API section must be updated accordingly.
Does this affect the completion percentage of this task?
Updated by Junxiao Shi over 5 years ago
Question: Do we consider an
EndpointID=0
as a broadcast address and other values as unicast? or anullptr
as broadcast address and others as unicast?
The convention described in NDN LAN thesis and implemented in esp8266ndn is:
- EndpointId zero means "default". It means broadcast for broadcast-capable interfaces, such as Ethernet. It still means unicast for point-to-point interfaces, such as TCP tunnel.
- EndpointId is not nilable so
nullptr
is not a valid value for this field.
NFD Developer Guide strategy API section must be updated accordingly.
Does this affect the completion percentage of this task?
Yes.
Updated by Md Ashiqur Rahman over 5 years ago
If I wish to set the default endpoint=0
for LINK_TYPE_AD_HOC,
auto endpoint = inRecord.getEndpointId();
if (inRecord.getFace().getId() == ingress.face.getId() &&
inRecord.getEndpointId() == ingress.endpoint &&
inRecord.getFace().getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
continue;
}
else if (inRecord.getFace().getId() == ingress.face.getId() &&
inRecord.getFace().getLinkType() == ndn::nfd::LINK_TYPE_AD_HOC) {
endpoint = 0;
}
pendingDownstreams.emplace(&inRecord.getFace(), endpoint);
the current inRecord.getEndpointId()
is non-const. However, as we discussed previously, to update the tables too with FaceEndpoint, should I set as shown in the code snippet and later when we add the new FaceEndpoint class in tables, then do a const_cast
?
Updated by Md Ashiqur Rahman over 5 years ago
To-do: Developer guide update: #4849-14
Updated by Junxiao Shi over 5 years ago
nfd:commit:c70794810592a90847656a97caf27f0326668240 breaks self-learning strategy.
Forwarder::onContentStoreMiss
inserts PIT in-record with EndpointId=0.SelfLearningStrategy::afterReceiveInterest
attempts to insertSelfLearningStrategy::InRecordInfo
to a PIT in-record with proper EndpointId.- The latter segfaults because the PIT in-record does not exist.
To fix this error, the ingress
passed to strategy needs to set EndpointId=0 as well.
Updated by Davide Pesavento over 4 years ago
- Status changed from In Progress to Abandoned