ndns-dig: adapt to the fact that NDN testbed does not have root zone
- Enable dig to set the start label during iterative process.
- Enable validation of intermediate results with an option to disable
it
Change-Id: I221e3c328c875ad06a1f8094f1004e68d9d46a57
diff --git a/src/clients/iterative-query-controller.cpp b/src/clients/iterative-query-controller.cpp
index c5e5104..be3f9f8 100644
--- a/src/clients/iterative-query-controller.cpp
+++ b/src/clients/iterative-query-controller.cpp
@@ -17,6 +17,7 @@
* NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "validator.hpp"
#include "iterative-query-controller.hpp"
#include "logger.hpp"
#include <iostream>
@@ -30,14 +31,14 @@
const time::milliseconds& interestLifetime,
const QuerySucceedCallback& onSucceed,
const QueryFailCallback& onFail,
- Face& face)
+ Face& face,
+ Validator* validator)
: QueryController(dstLabel, rrType, interestLifetime, onSucceed, onFail, face)
+ , m_validator(validator)
, m_step(QUERY_STEP_QUERY_NS)
, m_nFinishedComps(0)
, m_nTryComps(1)
{
- if (m_dstLabel.size() == 1) // the first one is to Query RR directly
- m_step = QUERY_STEP_QUERY_RR;
}
void
@@ -70,7 +71,22 @@
NDNS_LOG_TRACE("[* -> *] get a " << ndnsType
<< " Response: " << data.getName());
-
+ if (m_validator == nullptr) {
+ this->onDataValidated(make_shared<Data>(data), ndnsType);
+ }
+ else {
+ m_validator->validate(data,
+ bind(&IterativeQueryController::onDataValidated, this, _1, ndnsType),
+ [this] (const shared_ptr<const Data>& data, const std::string& str) {
+ NDNS_LOG_WARN("data: " << data->getName() << " fails verification");
+ this->abort();
+ }
+ );
+ }
+}
+void
+IterativeQueryController::onDataValidated(const shared_ptr<const Data>& data, NdnsType ndnsType)
+{
switch (m_step) {
case QUERY_STEP_QUERY_NS:
if (ndnsType == NDNS_NACK) {
@@ -118,9 +134,9 @@
this->express(this->makeLatestInterest()); // express new Expres
else if (m_step == QUERY_STEP_ANSWER_STUB) {
NDNS_LOG_TRACE("query ends: " << *this);
- Response re = this->parseFinalResponse(data);
+ Response re = this->parseFinalResponse(*data);
if (m_onSucceed != nullptr)
- m_onSucceed(data, re);
+ m_onSucceed(*data, re);
else
NDNS_LOG_TRACE("succeed callback is nullptr");
}
@@ -137,6 +153,9 @@
void
IterativeQueryController::start()
{
+ if (m_dstLabel.size() == m_nFinishedComps)
+ m_step = QUERY_STEP_QUERY_RR;
+
Interest interest = this->makeLatestInterest();
express(interest);
}
diff --git a/src/clients/iterative-query-controller.hpp b/src/clients/iterative-query-controller.hpp
index c97cc66..714a504 100644
--- a/src/clients/iterative-query-controller.hpp
+++ b/src/clients/iterative-query-controller.hpp
@@ -26,6 +26,7 @@
#include "query-controller.hpp"
#include "config.hpp"
#include "common.hpp"
+#include "validator.hpp"
#include <ndn-cxx/common.hpp>
#include <ndn-cxx/data.hpp>
@@ -59,7 +60,7 @@
IterativeQueryController(const Name& dstLabel, const name::Component& rrType,
const time::milliseconds& interestLifetime,
const QuerySucceedCallback& onSucceed, const QueryFailCallback& onFail,
- Face& face);
+ Face& face, Validator* validator = nullptr);
virtual void
start();
@@ -75,6 +76,9 @@
void
onData(const ndn::Interest& interest, const Data& data);
+ void
+ onDataValidated(const shared_ptr<const Data>& data, NdnsType ndnsType);
+
/**
* @brief change the Controller state according to timeout. For current,
* abort the query when timeout
@@ -98,13 +102,13 @@
void
express(const Interest& interest);
+public:
void
- setNFinishedComps(size_t finished)
+ setStartComponentIndex(size_t finished)
{
m_nFinishedComps = finished;
}
-public:
QueryStep
getStep() const
{
@@ -124,6 +128,7 @@
}
protected:
+ Validator* m_validator;
/**
* @brief current query step
*/
diff --git a/src/clients/query-controller.hpp b/src/clients/query-controller.hpp
index 778d563..7729ea2 100644
--- a/src/clients/query-controller.hpp
+++ b/src/clients/query-controller.hpp
@@ -68,6 +68,9 @@
virtual bool
hasEnded() = 0;
+ virtual void
+ setStartComponentIndex(size_t startIndex) = 0;
+
public:
////////////////
// getter
diff --git a/tests/unit/clients/iterative-query-controller.cpp b/tests/unit/clients/iterative-query-controller.cpp
index 0346419..7713a5b 100644
--- a/tests/unit/clients/iterative-query-controller.cpp
+++ b/tests/unit/clients/iterative-query-controller.cpp
@@ -98,7 +98,7 @@
// IterativeQueryController is a whole process
// the tester should not send Interest one by one
// instead of starting it and letting it handle Interest/Data automatically
- ctr->setNFinishedComps(1);
+ ctr->setStartComponentIndex(1);
ctr->start();
diff --git a/tools/ndns-dig.cpp b/tools/ndns-dig.cpp
index 18142a0..29afa4f 100644
--- a/tools/ndns-dig.cpp
+++ b/tools/ndns-dig.cpp
@@ -35,26 +35,36 @@
#include <memory>
#include <string>
+NDNS_LOG_INIT("NdnsDig");
+
namespace ndn {
namespace ndns {
-NDNS_LOG_INIT("NdnsDig");
class NdnsDig
{
public:
NdnsDig(const Name& hint, const Name& dstLabel,
- const name::Component& rrType)
+ const name::Component& rrType, bool shouldValidateIntermediate)
: m_dstLabel(dstLabel)
, m_rrType(rrType)
, m_hint(hint)
, m_interestLifetime(DEFAULT_INTEREST_LIFETIME)
, m_validator(m_face)
- , m_ctr(new IterativeQueryController(m_dstLabel, m_rrType, m_interestLifetime,
- bind(&NdnsDig::onSucceed, this, _1, _2),
- bind(&NdnsDig::onFail, this, _1, _2),
- m_face))
+ , m_shouldValidateIntermediate(shouldValidateIntermediate)
, m_hasError(false)
{
+ if (m_shouldValidateIntermediate)
+ m_ctr = std::unique_ptr<IterativeQueryController>
+ (new IterativeQueryController(m_dstLabel, m_rrType, m_interestLifetime,
+ bind(&NdnsDig::onSucceed, this, _1, _2),
+ bind(&NdnsDig::onFail, this, _1, _2),
+ m_face, &m_validator));
+ else
+ m_ctr = std::unique_ptr<IterativeQueryController>
+ (new IterativeQueryController(m_dstLabel, m_rrType, m_interestLifetime,
+ bind(&NdnsDig::onSucceed, this, _1, _2),
+ bind(&NdnsDig::onFail, this, _1, _2),
+ m_face, nullptr));
}
void
@@ -70,7 +80,7 @@
m_face.processEvents();
}
catch (std::exception& e) {
- NDNS_LOG_FATAL("Error: Face fails to process events: " << e.what());
+ std::cerr << "Error: " << e.what();
m_hasError = true;
}
}
@@ -82,6 +92,12 @@
NDNS_LOG_TRACE("application stops.");
}
+ void
+ setStartZone(const Name& start)
+ {
+ m_ctr->setStartComponentIndex(start.size());
+ }
+
private:
void
onSucceed(const Data& data, const Response& response)
@@ -190,6 +206,7 @@
Face m_face;
Validator m_validator;
+ bool m_shouldValidateIntermediate;
std::unique_ptr<QueryController> m_ctr;
bool m_hasError;
@@ -211,6 +228,9 @@
int ttl = 4;
string rrType = "TXT";
string dstFile;
+ bool shouldValidateIntermediate = true;
+ Name start("/ndn");
+
try {
namespace po = boost::program_options;
po::variables_map vm;
@@ -224,6 +244,8 @@
("rrtype,t", po::value<std::string>(&rrType), "set request RR Type. default: TXT")
("dstFile,d", po::value<std::string>(&dstFile), "set output file of the received Data. "
"if omitted, not print; if set to be -, print to stdout; else print to file")
+ ("start,s", po::value<Name>(&start)->default_value("/ndn"), "set first zone to query")
+ ("not-validate,n", "trigger not validate intermediate results")
;
po::options_description hidden("Hidden Options");
@@ -255,17 +277,40 @@
std::cout << visible << std::endl;
return 0;
}
+
+ if (!start.isPrefixOf(dstLabel)) {
+ std::cerr << "Error: start zone " << start << " is not prefix of the target label "
+ << dstLabel << std::endl;
+ return 1;
+ }
+
+ if (vm.count("not-validate")) {
+ shouldValidateIntermediate = false;
+ }
+
+ if (ttl < 0) {
+ std::cerr << "Error: ttl parameter cannot be negative" << std::endl;
+ return 1;
+ }
}
catch (const std::exception& ex) {
std::cerr << "Parameter Error: " << ex.what() << std::endl;
- return 0;
+ return 1;
}
- ndn::ndns::NdnsDig dig("", dstLabel, ndn::name::Component(rrType));
- dig.setInterestLifetime(ndn::time::milliseconds(ttl * 1000));
+ NDNS_LOG_TRACE("validateIntermediate=" << shouldValidateIntermediate);
+
+ ndn::ndns::NdnsDig dig("", dstLabel, ndn::name::Component(rrType), !shouldValidateIntermediate);
+ dig.setInterestLifetime(ndn::time::seconds(ttl));
dig.setDstFile(dstFile);
+ // Due to ndn testbed does not contain the root zone
+ // dig here starts from the TLD (Top-level Domain)
+ // precondition is that TLD : 1) only contains one component in its name; 2) its name is routable
+ dig.setStartZone(start);
+
dig.run();
+
if (dig.hasError())
return 1;
else