mgmt: Add addDelegatedRrset to automatically create AUTH records
Change-Id: I4d87ca52d3d176a8541236ec31526f1ca6033e34
diff --git a/src/daemon/rrset-factory.cpp b/src/daemon/rrset-factory.cpp
index 9395f42..2830dac 100644
--- a/src/daemon/rrset-factory.cpp
+++ b/src/daemon/rrset-factory.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+ * Copyright (c) 2014-2017, 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.
@@ -223,6 +223,31 @@
return rrset;
}
+Rrset
+RrsetFactory::generateAuthRrset(const Name& label,
+ const name::Component& type,
+ const uint64_t version,
+ time::seconds ttl)
+{
+ if (!m_checked) {
+ BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
+ }
+
+ if (ttl == DEFAULT_RR_TTL)
+ ttl = m_zone.getTtl();
+
+ Name name;
+ Rrset rrset;
+ std::tie(rrset, name) = generateBaseRrset(label, type, version, ttl);
+
+ Data data(name);
+
+ setContentType(data, NDNS_AUTH, ttl);
+ sign(data);
+ rrset.setData(data.wireEncode());
+
+ return rrset;
+}
void
RrsetFactory::sign(Data& data)
diff --git a/src/daemon/rrset-factory.hpp b/src/daemon/rrset-factory.hpp
index e5165d3..083b8a5 100644
--- a/src/daemon/rrset-factory.hpp
+++ b/src/daemon/rrset-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+ * Copyright (c) 2014-2017, 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.
@@ -73,6 +73,12 @@
const std::vector<std::string>& contents);
Rrset
+ generateAuthRrset(const Name& label,
+ const name::Component& type,
+ const uint64_t version,
+ time::seconds ttl);
+
+ Rrset
generateCertRrset(const Name& label,
const name::Component& type,
const uint64_t version,
diff --git a/src/mgmt/management-tool.cpp b/src/mgmt/management-tool.cpp
index 9ac19e5..b2f9d44 100644
--- a/src/mgmt/management-tool.cpp
+++ b/src/mgmt/management-tool.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+ * Copyright (c) 2014-2017, 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.
@@ -197,8 +197,73 @@
}
void
+ManagementTool::addMultiLevelLabelRrset(Rrset& rrset,
+ RrsetFactory& zoneRrFactory,
+ const time::seconds& authTtl)
+{
+ const Name& label = rrset.getLabel();
+
+ // Check whether it is legal to insert the rrset
+ for (size_t i = 1; i <= label.size() - 1; i++) {
+ Name prefix = label.getPrefix(i);
+ Rrset prefixNsRr(rrset.getZone());
+ prefixNsRr.setLabel(prefix);
+ prefixNsRr.setType(label::NS_RR_TYPE);
+ if (m_dbMgr.find(prefixNsRr)) {
+ Data data(prefixNsRr.getData());
+ if (data.getContentType() == NDNS_LINK) {
+ BOOST_THROW_EXCEPTION(Error("Cannot override " + boost::lexical_cast<std::string>(prefixNsRr) + " (NDNS_LINK)"));
+ }
+ }
+ }
+
+ // check that it does not override existing AUTH
+ if (rrset.getType() == label::NS_RR_TYPE) {
+ Rrset rrsetCopy = rrset;
+ if (m_dbMgr.find(rrsetCopy)) {
+ if (Data(rrsetCopy.getData()).getContentType() == NDNS_AUTH) {
+ BOOST_THROW_EXCEPTION(Error("Cannot override " + boost::lexical_cast<std::string>(rrsetCopy) + " (NDNS_AUTH)"));
+ }
+ }
+ }
+
+ for (size_t i = 1; i <= label.size() - 1; i++) {
+ Name prefix = label.getPrefix(i);
+ Rrset prefixNsRr(rrset.getZone());
+ prefixNsRr.setLabel(prefix);
+ prefixNsRr.setType(label::NS_RR_TYPE);
+ if (m_dbMgr.find(prefixNsRr)) {
+ NDNS_LOG_INFO("NDNS_AUTH Rrset Label=" << prefix << " is already existed, insertion skipped");
+ continue;
+ }
+
+ Rrset authRr = zoneRrFactory.generateAuthRrset(prefix, label::NS_RR_TYPE,
+ VERSION_USE_UNIX_TIMESTAMP, authTtl);
+ NDNS_LOG_INFO("Adding NDNS_AUTH " << authRr);
+ m_dbMgr.insert(authRr);
+ }
+
+ checkRrsetVersion(rrset);
+ NDNS_LOG_INFO("Adding " << rrset);
+ m_dbMgr.insert(rrset);
+}
+
+void
ManagementTool::addRrset(Rrset& rrset)
{
+ if (rrset.getLabel().size() > 1) {
+ throw Error("Cannot add rrset with label size > 1, should use addMultiLevelLabelRrset instead");
+ }
+
+ // check that it does not override existing AUTH
+ Rrset rrsetCopy = rrset;
+ rrsetCopy.setType(label::NS_RR_TYPE);
+ if (m_dbMgr.find(rrsetCopy)) {
+ if (Data(rrsetCopy.getData()).getContentType() == NDNS_AUTH) {
+ BOOST_THROW_EXCEPTION(Error("Can not add this Rrset: it overrides a NDNS_AUTH record"));
+ }
+ }
+
checkRrsetVersion(rrset);
NDNS_LOG_INFO("Added " << rrset);
m_dbMgr.insert(rrset);
diff --git a/src/mgmt/management-tool.hpp b/src/mgmt/management-tool.hpp
index d41bd2b..e63358d 100644
--- a/src/mgmt/management-tool.hpp
+++ b/src/mgmt/management-tool.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+ * Copyright (c) 2014-2017, 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.
@@ -25,6 +25,7 @@
#include "./daemon/zone.hpp"
#include "./daemon/db-mgr.hpp"
#include "./daemon/rrset.hpp"
+#include "./daemon/rrset-factory.hpp"
#include "./clients/response.hpp"
#include <stdexcept>
@@ -75,19 +76,18 @@
*
* Specifically, It will generate a KSK and a DSK (and their certificates) to the following
* places:
- * 1) Local NDNS database: a new zone is added.
- * 2) Local NDNS database: an ID-CERT of the DSK is added.
- * 3) KeyChain: an identity named with zone name is added.
- * 4) KeyChain: a KSK and its self-signed certificate is added. The ownership of the KSK is the
+ * 1. Local NDNS database: a new zone is added.
+ * 2. Local NDNS database: an ID-CERT of the DSK is added.
+ * 3. KeyChain: an identity named with zone name is added.
+ * 4. KeyChain: a KSK and its self-signed certificate is added. The ownership of the KSK is the
* parent zone.
- * 5) KeyChain: a DSK and its KSK signed certificate is added.
+ * 5. KeyChain: a DSK and its KSK signed certificate is added.
*
- * -SS.cert (self-signed)
- * -SKS.cert (self's Key signed)
- * -PKS.cert (parent's Key Signed)
+ * - SS.cert (self-signed)
+ * - SKS.cert (self's Key signed)
+ * - PKS.cert (parent's Key Signed)
*
- * @attention
- * 1) to create root zone, supply zoneName and parentZoneName both with ROOT_ZONE
+ * @note To create root zone, supply zoneName and parentZoneName both with ROOT_ZONE
*
* @param zoneName zone's name
* @param parentZoneName parent zone's name
@@ -96,7 +96,7 @@
* should not be empty)
* @param kskCertName if given, a zone will be created with this ksk certificate
* @param dskCertName if given, a zone will be created with this dsk certificate and provided
- * ksk certificate will be ignored
+ * ksk certificate will be ignored
*/
void
createZone(const Name& zoneName,
@@ -124,7 +124,7 @@
void
exportCertificate(const Name& certName, const std::string& outFile = DEFAULT_IO);
- /** @brief add rrset to the NDNS local database
+ /** @brief Add rrset to the NDNS local database
*
* This overload is capable of adding any data to the rrset as long as the supplied data is
* valid.
@@ -145,13 +145,44 @@
const Name& dskCertName = DEFAULT_CERT,
const ndn::io::IoEncoding encoding = ndn::io::BASE64);
- /** @brief add rrset to the NDNS local database
+ /** @brief Add rrset to the NDNS local database
+ *
+ * @throw Error if the @p rrset label size is larger than 1 or @p rrset will override an
+ * existing AUTH record
*
* @param rrset rrset
*/
void
addRrset(Rrset& rrset);
+ /** @brief Add rrset with multi-level label to the NDNS local database
+ *
+ * The appropriate AUTH records will be created automatically if they do not yet exist. The
+ * existing records are kept intact.
+ *
+ * @throw Error If one of the levels has been delegated to another zone. For example, if
+ * there is an NS record with label `/foo`, then inserting @p rrset having a
+ * multi-level label that use `/foo` as prefix will cause an error.
+ *
+ * @throw Error If @p rrset will override an AUTH record. For example, if there is already
+ * an AUTH record with label `/foo/bar`, then inserting NS-type @p rrset that
+ * has the the same label will cause an error.
+ *
+ * For example, inserting a rrset with `/foo/bar/test` label and TXT type into zone `/zone/NDNS`
+ * will create:
+ * - `/zone/NDNS/foo/NS` (.ContentType AUTH)
+ * - `/zone/NDNS/foo/bar/NS` (.ContentType AUTH)
+ * - `/zone/NDNS/foo/bar/test/TXT` (.ContentType NDNS-Resp)
+ *
+ * @param rrset rrset
+ * @param zoneRrFactory that is used for generate AUTH packet
+ * @param authTtl
+ */
+ void
+ addMultiLevelLabelRrset(Rrset& rrset,
+ RrsetFactory& zoneRrFactory,
+ const time::seconds& authTtl);
+
/** @brief remove rrset from the NDNS local database
*
* @param zoneName the name of the zone holding the rrset
diff --git a/tests/unit/validator.cpp b/tests/unit/validator.cpp
index ff9547f..293cff0 100644
--- a/tests/unit/validator.cpp
+++ b/tests/unit/validator.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+ * Copyright (c) 2014-2017, 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.
@@ -122,7 +122,7 @@
BOOST_CHECK_EQUAL(m_keyChain.doesCertificateExist(certName), true);
auto cert = m_keyChain.getCertificate(certName);
m_face.getIoService().post([this, cert] {
- m_face.receive<Data>(*cert);
+ m_face.receive(*cert);
});
}
diff --git a/tools/ndns-add-rr.cpp b/tools/ndns-add-rr.cpp
index 2ec81aa..4e0a757 100644
--- a/tools/ndns-add-rr.cpp
+++ b/tools/ndns-add-rr.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+ * Copyright (c) 2014-2017, 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.
@@ -30,6 +30,8 @@
#include <string>
+NDNS_LOG_INIT("AddRrTool")
+
int
main(int argc, char* argv[])
{
@@ -159,7 +161,13 @@
}
ndn::ndns::ManagementTool tool(db, keyChain);
- tool.addRrset(rrset);
+
+ if (label.size() > 1) {
+ NDNS_LOG_TRACE("add multi-level label Rrset, using the same TTL as the Rrset");
+ tool.addMultiLevelLabelRrset(rrset, rrsetFactory, ttl);
+ } else {
+ tool.addRrset(rrset);
+ }
/// @todo Report success or failure
// May be also show the inserted record in ndns-list-zone format