Introduce Denial-of-Existence (DoE) for Nack response.
Note this commit changes how names are stored in the database, compliant
to the canonical order.
Change-Id: I9857aaefc1f7da08ff53eff43c8f8c8bd5443953
Refs: #4152
diff --git a/src/clients/iterative-query-controller.cpp b/src/clients/iterative-query-controller.cpp
index 2b56426..442f9dc 100644
--- a/src/clients/iterative-query-controller.cpp
+++ b/src/clients/iterative-query-controller.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California.
+ * Copyright (c) 2014-2018, Regents of the University of California.
*
* This file is part of NDNS (Named Data Networking Domain Name Service).
* See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -68,11 +68,22 @@
NDNS_LOG_TRACE("[* -> *] get a " << contentType
<< " Response: " << data.getName());
- if (m_validator == nullptr) {
- this->onDataValidated(data, contentType);
+
+ const Data* toBeValidatedData = nullptr;
+ if (contentType == NDNS_NACK) {
+ m_doe = Data(data.getContent().blockFromValue());
+ toBeValidatedData = &m_doe;
+ contentType = NDNS_DOE;
}
else {
- m_validator->validate(data,
+ toBeValidatedData = &data;
+ }
+
+ if (m_validator == nullptr) {
+ this->onDataValidated(*toBeValidatedData, contentType);
+ }
+ else {
+ m_validator->validate(*toBeValidatedData,
bind(&IterativeQueryController::onDataValidated, this, _1, contentType),
[this] (const Data& data, const security::v2::ValidationError& err) {
NDNS_LOG_WARN("data: " << data.getName() << " fails verification");
@@ -81,6 +92,7 @@
);
}
}
+
void
IterativeQueryController::onDataValidated(const Data& data, NdnsContentType contentType)
{
@@ -90,8 +102,18 @@
switch (m_step) {
case QUERY_STEP_QUERY_NS:
- if (contentType == NDNS_NACK) {
- m_step = QUERY_STEP_QUERY_RR;
+ if (contentType == NDNS_DOE) {
+ // check if requested record is absent by looking up in doe
+ if (isAbsentByDoe(data)) {
+ m_step = QUERY_STEP_QUERY_RR;
+ }
+ else {
+ std::ostringstream oss;
+ oss << "In onDataValidated, absence of record can not be infered from DoE.";
+ oss << " Last query:" << m_lastLabelType << " ";
+ oss << *this;
+ BOOST_THROW_EXCEPTION(std::runtime_error(oss.str()));
+ }
}
else if (contentType == NDNS_LINK) {
Link link(data.wireEncode());
@@ -236,10 +258,27 @@
+ oss.str()));
}
+ m_lastLabelType = Name(query.getRrLabel()).append(query.getRrType());
Interest interest = query.toInterest();
return interest;
}
+bool
+IterativeQueryController::isAbsentByDoe(const Data& data) const
+{
+ std::pair<Name, Name> range = Response::wireDecodeDoe(data.getContent());
+
+ // should not be simple <, use our own definition of compare
+ if (range.first < m_lastLabelType && m_lastLabelType < range.second) {
+ return true;
+ }
+ if (range.second < range.first &&
+ (m_lastLabelType < range.first || range.second < m_lastLabelType)) {
+ return true;
+ }
+ return false;
+}
+
std::ostream&
operator<<(std::ostream& os, const IterativeQueryController::QueryStep step)
{
diff --git a/src/clients/iterative-query-controller.hpp b/src/clients/iterative-query-controller.hpp
index 83bf856..a04424e 100644
--- a/src/clients/iterative-query-controller.hpp
+++ b/src/clients/iterative-query-controller.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California.
+ * Copyright (c) 2014-2018, Regents of the University of California.
*
* This file is part of NDNS (Named Data Networking Domain Name Service).
* See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -79,6 +79,11 @@
void
onData(const ndn::Interest& interest, const Data& data);
+ /**
+ * @brief called when any data are validated.
+ * It will unwrap the NACK record,
+ * so onSucceed callback will be called with only inner DoE
+ */
void
onDataValidated(const Data& data, NdnsContentType contentType);
@@ -130,6 +135,10 @@
return m_nTryComps;
}
+private:
+ bool
+ isAbsentByDoe(const Data& data) const;
+
protected:
security::v2::Validator* m_validator;
/**
@@ -151,6 +160,8 @@
private:
Block m_lastLink;
+ Data m_doe;
+ Name m_lastLabelType;
ndn::InMemoryStorage* m_nsCache;
};
diff --git a/src/clients/response.cpp b/src/clients/response.cpp
index a23bc3c..5f223d3 100644
--- a/src/clients/response.cpp
+++ b/src/clients/response.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California.
+ * Copyright (c) 2014-2018, Regents of the University of California.
*
* This file is part of NDNS (Named Data Networking Domain Name Service).
* See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -93,6 +93,16 @@
}
}
+std::pair<Name, Name>
+Response::wireDecodeDoe(const Block& wire)
+{
+ wire.parse();
+ if (wire.elements().size() != 2) {
+ BOOST_THROW_EXCEPTION(Error("Unexpected number of components while decoding DOE record"));
+ }
+ return std::make_pair(Name(wire.elements().front()), Name(wire.elements().back()));
+}
+
bool
Response::fromData(const Name& zone, const Data& data)
{
diff --git a/src/clients/response.hpp b/src/clients/response.hpp
index a33e42a..a97fb76 100644
--- a/src/clients/response.hpp
+++ b/src/clients/response.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California.
+ * Copyright (c) 2014-2018, Regents of the University of California.
*
* This file is part of NDNS (Named Data Networking Domain Name Service).
* See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -40,7 +40,7 @@
/**
* @brief Default life time of resource record
*/
-const time::seconds DEFAULT_RR_FRESHNESS_PERIOD(3600);
+const time::seconds DEFAULT_RR_FRESHNESS_PERIOD = 3600_s;
/**
@@ -50,6 +50,12 @@
class Response
{
public:
+ class Error : public ndn::tlv::Error
+ {
+ public:
+ using ndn::tlv::Error::Error;
+ };
+
Response();
Response(const Name& zone, const name::Component& queryType);
@@ -112,6 +118,9 @@
size_t
wireEncode(EncodingImpl<T>& block) const;
+ static std::pair<Name, Name>
+ wireDecodeDoe(const Block& wire);
+
public:
///////////////////////////////////////////////
// getter and setter