security: Add option to disable infrastructure interest in CertificateFetcherDirectFetch
Refs: #4879
Change-Id: I4ee7f831fde1fe6e951857c279546f7b7433def0
diff --git a/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.cpp b/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.cpp
index 2e6c8f8..7a4cb42 100644
--- a/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.cpp
+++ b/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -33,6 +33,12 @@
}
void
+CertificateFetcherDirectFetch::setSendDirectInterestOnly(bool wantDirectInterestOnly)
+{
+ m_wantDirectInterestOnly = wantDirectInterestOnly;
+}
+
+void
CertificateFetcherDirectFetch::doFetch(const shared_ptr<CertificateRequest>& keyRequest,
const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation)
@@ -56,11 +62,33 @@
Interest directInterest(keyRequest->interest);
directInterest.refreshNonce();
directInterest.setTag(make_shared<lp::NextHopFaceIdTag>(incomingFaceId));
- m_face.expressInterest(directInterest, nullptr, nullptr, nullptr);
+
+ if (!m_wantDirectInterestOnly) {
+ // disable callbacks
+ m_face.expressInterest(directInterest, nullptr, nullptr, nullptr);
+ }
+ else {
+ m_face.expressInterest(directInterest,
+ [=] (const Interest& interest, const Data& data) {
+ dataCallback(data, keyRequest, state, continueValidation);
+ },
+ [=] (const Interest& interest, const lp::Nack& nack) {
+ nackCallback(nack, keyRequest, state, continueValidation);
+ },
+ [=] (const Interest& interest) {
+ timeoutCallback(keyRequest, state, continueValidation);
+ });
+ }
}
- // send infrastructure Interest
- CertificateFetcherFromNetwork::doFetch(keyRequest, state, continueValidation);
+ if (!m_wantDirectInterestOnly) {
+ // send infrastructure Interest
+ CertificateFetcherFromNetwork::doFetch(keyRequest, state, continueValidation);
+ }
+ else if (incomingFaceId == 0) {
+ state->fail({ValidationError::Code::CANNOT_RETRIEVE_CERT,
+ "Cannot direct fetch certificate as IncomingFaceId tag is not set"});
+ }
}
} // namespace v2
diff --git a/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp b/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp
index 0ac93aa..0a5c480 100644
--- a/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp
+++ b/ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -43,10 +43,19 @@
explicit
CertificateFetcherDirectFetch(Face& face);
+ /**
+ * If \p wantDirectInterestOnly, only the direct Interest will be sent out.
+ */
+ void
+ setSendDirectInterestOnly(bool wantDirectInterestOnly);
+
protected:
void
doFetch(const shared_ptr<CertificateRequest>& keyRequest, const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation) override;
+
+private:
+ bool m_wantDirectInterestOnly = false;
};
} // namespace v2
diff --git a/ndn-cxx/security/v2/certificate-fetcher-from-network.hpp b/ndn-cxx/security/v2/certificate-fetcher-from-network.hpp
index 4b570c3..35b960a 100644
--- a/ndn-cxx/security/v2/certificate-fetcher-from-network.hpp
+++ b/ndn-cxx/security/v2/certificate-fetcher-from-network.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -48,7 +48,6 @@
doFetch(const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation) override;
-private:
/**
* @brief Callback invoked when certificate is retrieved.
*/
diff --git a/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp b/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp
index e2d543c..7e513c6 100644
--- a/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp
+++ b/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -58,6 +58,13 @@
CertificateFetcherDirectFetch>
{
public:
+ enum class ResponseType {
+ INFRASTRUCTURE,
+ DIRECT,
+ BOTH
+ };
+
+public:
CertificateFetcherDirectFetchFixture()
: data("/Security/V2/ValidatorFixture/Sub1/Sub3/Data")
, interest("/Security/V2/ValidatorFixture/Sub1/Sub3/Interest")
@@ -76,7 +83,14 @@
processInterest = [this] (const Interest& interest) {
auto nextHopFaceIdTag = interest.template getTag<lp::NextHopFaceIdTag>();
if (nextHopFaceIdTag == nullptr) {
- makeResponse(interest); // respond only to the "infrastructure" interest
+ if (responseType == ResponseType::INFRASTRUCTURE || responseType == ResponseType::BOTH) {
+ makeResponse(interest);
+ }
+ }
+ else {
+ if (responseType == ResponseType::DIRECT || responseType == ResponseType::BOTH) {
+ makeResponse(interest);
+ }
}
};
}
@@ -84,10 +98,17 @@
void
makeResponse(const Interest& interest);
+ void
+ setResponseType(ResponseType type)
+ {
+ responseType = type;
+ }
+
public:
Data data;
Interest interest;
Interest interestNoTag;
+ ResponseType responseType = ResponseType::INFRASTRUCTURE;
};
template<>
@@ -137,11 +158,24 @@
}
}
+BOOST_FIXTURE_TEST_CASE(ValidateSuccessDataDirectOnly, CertificateFetcherDirectFetchFixture<Cert>)
+{
+ setResponseType(ResponseType::DIRECT);
+ static_cast<CertificateFetcherDirectFetch&>(validator.getFetcher()).setSendDirectInterestOnly(true);
+
+ VALIDATE_SUCCESS(this->data, "Should get accepted, direct interests bring certs");
+ BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 2);
+
+ for (const auto& sentInterest : this->face.sentInterests) {
+ BOOST_CHECK(sentInterest.template getTag<lp::NextHopFaceIdTag>() != nullptr);
+ }
+}
+
BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateFailureData, T, Failures, CertificateFetcherDirectFetchFixture<T>)
{
VALIDATE_FAILURE(this->data, "Should fail, as all interests either NACKed or timeout");
// Direct fetcher sends two interests each time - to network and face
- // 3 retries on nack or timeout (2 * (1 + 3) = 4)
+ // 3 retries on nack or timeout (2 * (1 + 3) = 8)
BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 8);
// odd interests
@@ -157,6 +191,34 @@
}
}
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateFailureDataDirectOnly, T, Failures, CertificateFetcherDirectFetchFixture<T>)
+{
+ this->setResponseType(CertificateFetcherDirectFetchFixture<T>::ResponseType::DIRECT);
+ static_cast<CertificateFetcherDirectFetch&>(this->validator.getFetcher()).setSendDirectInterestOnly(true);
+
+ VALIDATE_FAILURE(this->data, "Should fail, as all interests either NACKed or timeout");
+ // Direct fetcher sends two interests each time - to network and face
+ // 3 retries on nack or timeout (1 + 3 = 4)
+ BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 4);
+
+ for (const auto& sentInterest : this->face.sentInterests) {
+ BOOST_CHECK(sentInterest.template getTag<lp::NextHopFaceIdTag>() != nullptr);
+ }
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateFailureDataNoTagDirectOnly, T, Failures, CertificateFetcherDirectFetchFixture<T>)
+{
+ this->setResponseType(CertificateFetcherDirectFetchFixture<T>::ResponseType::DIRECT);
+ static_cast<CertificateFetcherDirectFetch&>(this->validator.getFetcher()).setSendDirectInterestOnly(true);
+
+ this->data.template removeTag<lp::IncomingFaceIdTag>();
+ this->interest.template removeTag<lp::IncomingFaceIdTag>();
+
+ VALIDATE_FAILURE(this->data, "Should fail, as no interests are expected");
+ BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 0);
+ BOOST_CHECK(this->lastError.getCode() != ValidationError::Code::IMPLEMENTATION_ERROR);
+}
+
BOOST_FIXTURE_TEST_CASE(ValidateSuccessInterest, CertificateFetcherDirectFetchFixture<Cert>)
{
VALIDATE_SUCCESS(this->interest, "Should get accepted, normal and/or direct interests bring certs");
diff --git a/tests/unit/security/v2/validator-fixture.hpp b/tests/unit/security/v2/validator-fixture.hpp
index 5bd195e..e5079bc 100644
--- a/tests/unit/security/v2/validator-fixture.hpp
+++ b/tests/unit/security/v2/validator-fixture.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -45,6 +45,7 @@
, validator(make_unique<ValidationPolicy>(), make_unique<CertificateFetcher>(face))
, policy(static_cast<ValidationPolicy&>(validator.getPolicy()))
, cache(100_days)
+ , lastError(ValidationError::Code::NO_ERROR)
{
processInterest = [this] (const Interest& interest) {
auto cert = cache.find(interest);
@@ -70,6 +71,7 @@
(expectSuccess ? "OK: " : "FAILED: ") + detailedInfo);
},
[&] (const Packet&, const ValidationError& error) {
+ lastError = error;
++nCallbacks;
BOOST_CHECK_MESSAGE(!expectSuccess,
(!expectSuccess ? "OK: " : "FAILED: ") + detailedInfo +
@@ -106,6 +108,7 @@
ValidationPolicy& policy;
CertificateCache cache;
+ ValidationError lastError;
private:
const static int s_mockPeriod;