Actions
Bug #3554
closedSegmentFetcher restarts from segment0 upon Nack
Start date:
06/07/2016
Due date:
% Done:
100%
Estimated time:
(Total: 0.50 h)
Description
Snippet to reproduce:
// g++ -o x -std=c++0x x.cpp $(pkg-config --cflags --libs libndn-cxx)
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/validator-null.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
namespace ndn {
namespace demo {
using util::DummyClientFace;
using util::SegmentFetcher;
KeyChain g_keyChain;
shared_ptr<Data>
makeData(const Name& name, bool isFinalBlock = false)
{
auto data = make_shared<Data>(name);
if (isFinalBlock) {
data->setMetaInfo(MetaInfo().setFinalBlockId(name.at(-1)));
}
g_keyChain.sign(*data, ndn::signingWithSha256());
return data;
}
int
main(int argc, char** argv)
{
DummyClientFace face;
int nNacks = 2;
face.onSendInterest.connect([&] (const Interest& interest) {
std::cout << interest << std::endl;
const Name& name = interest.getName();
if (!name.at(-1).isSegment()) {
auto data0 = makeData(Name(name).appendVersion().appendSegment(0));
face.getIoService().post([&face, data0] { face.receive(*data0); });
return;
}
uint64_t segmentNo = name.at(-1).toSegment();
if (segmentNo == 1 && nNacks-- > 0) {
lp::Nack nack(interest);
nack.setReason(lp::NackReason::DUPLICATE);
face.getIoService().post([&face, nack] { face.receive(nack); });
return;
}
auto data1 = makeData(name, segmentNo == 3);
face.getIoService().post([&face, data1] { face.receive(*data1); });
});
SegmentFetcher::fetch(face,
Interest("ndn:/A"),
make_shared<ValidatorNull>(),
bind([] { std::cout << "COMPLETE" << std::endl; }),
bind([] { std::cout << "ERROR" << std::endl; }));
face.processEvents();
return 0;
}
} // namespace demo
} // namespace ndn
int
main(int argc, char** argv)
{
return ndn::demo::main(argc, argv);
}
This snippet uses SegmentFetcher to fetch 4 segments.
The first and second Interests for segment1 would be responded with Nack-Duplicate.
All other responses are Data.
Expected: SegmentFetcher retrieves segment2 after receiving Data for segment1.
Actual: SegmentFetcher discards segment2 Data and restarts from segment0.
/A?ndn.ChildSelector=1&ndn.MustBeFresh=1&ndn.Nonce=369644762
/A/%FD%00%00%01Sz%F6%FC%1E/%00%01?ndn.ChildSelector=0&ndn.Nonce=509290956
/A/%FD%00%00%01Sz%F6%FC%1E/%00%01?ndn.ChildSelector=0&ndn.Nonce=944403614
/A/%FD%00%00%01Sz%F6%FC%1E/%00%01?ndn.ChildSelector=0&ndn.Nonce=1709422619
/A/%FD%00%00%01Sz%F6%FC%1E/%00%00?ndn.ChildSelector=0&ndn.Nonce=3626967908
/A/%FD%00%00%01Sz%F6%FC%1E/%00%01?ndn.ChildSelector=0&ndn.Nonce=2208639054
/A/%FD%00%00%01Sz%F6%FC%1E/%00%02?ndn.ChildSelector=0&ndn.Nonce=765477500
/A/%FD%00%00%01Sz%F6%FC%1E/%00%03?ndn.ChildSelector=0&ndn.Nonce=84957429
COMPLETE
Root cause: in SegmentFetcher::reExpressInterest, afterSegmentReceived
is always called with isSegmentZeroExpected=true
.
Actions