tools: Publish /localhop/ndn-autoconf/routable-prefixes from ndn-autoconfig-server
Change-Id: I2902b91cebf1f4b8ac1a7dabedb0f0cbd0a13b24
Refs: #1954
diff --git a/tools/ndn-autoconfig-server.cpp b/tools/ndn-autoconfig-server.cpp
index bc038e3..1a01061 100644
--- a/tools/ndn-autoconfig-server.cpp
+++ b/tools/ndn-autoconfig-server.cpp
@@ -26,46 +26,111 @@
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
+namespace ndn {
-void
+const static Name AUTOCONFIG_PREFIX = "/localhop/ndn-autoconf";
+const static Name LOCALHOP_HUB = "/localhop/ndn-autoconf/hub";
+const static Name LOCALHOP_ROUTABLE_PREFIXES = "/localhop/ndn-autoconf/routable-prefixes";
+
+static void
usage(const char* programName)
{
- std::cout << "Usage:\n" << programName << " [-h] [-V] Uri \n"
- << " -h - print usage and exit\n"
- << " -V - print version number and exit\n"
+ std::cout << "Usage:\n" << programName << " [-h] [-V] [-p prefix] [-p prefix] ... Uri \n"
+ << " -h - print usage and exit\n"
+ << " -V - print version number and exit\n"
+ << " -p prefix - the local prefix of the hub\n"
<< "\n"
<< " Uri - a FaceMgmt URI\n"
<< std::endl;
}
-using namespace ndn;
-
-class NdnAutoconfigServer
+class PrefixCollection : noncopyable
{
public:
- explicit
- NdnAutoconfigServer(const std::string& uri)
- : m_faceMgmtUri(uri)
+ bool
+ empty() const
{
+ return m_prefixes.empty();
}
void
- onInterest(const Name& name, const Interest& interest)
+ add(const Name& prefix)
{
- ndn::Data data(ndn::Name(interest.getName()).appendVersion());
- data.setFreshnessPeriod(ndn::time::hours(1)); // 1 hour
+ m_prefixes.push_back(prefix);
+ }
- // create and encode uri block
- Block uriBlock = dataBlock(tlv::nfd::Uri,
- reinterpret_cast<const uint8_t*>(m_faceMgmtUri.c_str()),
- m_faceMgmtUri.size());
- data.setContent(uriBlock);
- m_keyChain.sign(data);
- m_face.put(data);
+ template<bool T>
+ size_t
+ wireEncode(EncodingImpl<T>& encoder) const
+ {
+ size_t totalLength = 0;
+
+ for (std::vector<Name>::const_reverse_iterator i = m_prefixes.rbegin();
+ i != m_prefixes.rend(); ++i) {
+ totalLength += i->wireEncode(encoder);
+ }
+
+ totalLength += encoder.prependVarNumber(totalLength);
+ totalLength += encoder.prependVarNumber(tlv::Content);
+ return totalLength;
+ }
+
+ Block
+ wireEncode() const
+ {
+ Block block;
+
+ EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
+
+ EncodingBuffer buffer(estimatedSize);
+ wireEncode(buffer);
+
+ return buffer.block();
+ }
+
+private:
+ std::vector<Name> m_prefixes;
+};
+
+class NdnAutoconfigServer : noncopyable
+{
+public:
+ NdnAutoconfigServer(const std::string& hubFaceUri, const PrefixCollection& routablePrefixes)
+ {
+ KeyChain m_keyChain;
+
+ // pre-create hub Data
+ m_hubData = make_shared<Data>(Name(LOCALHOP_HUB).appendVersion());
+ m_hubData->setFreshnessPeriod(time::hours(1)); // 1 hour
+ m_hubData->setContent(dataBlock(tlv::nfd::Uri,
+ reinterpret_cast<const uint8_t*>(hubFaceUri.c_str()),
+ hubFaceUri.size()));
+ m_keyChain.sign(*m_hubData);
+
+ // pre-create routable prefix Data
+ if (!routablePrefixes.empty()) {
+ m_routablePrefixesData = make_shared<Data>(Name(LOCALHOP_ROUTABLE_PREFIXES).appendVersion());
+ m_routablePrefixesData->setContent(routablePrefixes.wireEncode());
+ m_routablePrefixesData->setFreshnessPeriod(time::seconds(5)); // 5s
+ m_keyChain.sign(*m_routablePrefixesData);
+ }
}
void
- onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
+ onHubInterest(const Name& name, const Interest& interest)
+ {
+ m_face.put(*m_hubData);
+ }
+
+ void
+ onRoutablePrefixesInterest(const Name& name, const Interest& interest)
+ {
+ m_face.put(*m_routablePrefixesData);
+ }
+
+ void
+ onRegisterFailed(const Name& prefix, const std::string& reason)
{
std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" <<
reason << ")" << std::endl;
@@ -73,29 +138,46 @@
}
void
- listen()
+ afterPrefixRegistered()
{
- m_face.setInterestFilter("/localhop/ndn-autoconf/hub",
- ndn::bind(&NdnAutoconfigServer::onInterest, this, _1, _2),
- ndn::RegisterPrefixSuccessCallback(),
- ndn::bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
+ BOOST_ASSERT(AUTOCONFIG_PREFIX.isPrefixOf(LOCALHOP_HUB));
+ m_face.setInterestFilter(LOCALHOP_HUB,
+ bind(&NdnAutoconfigServer::onHubInterest, this, _1, _2));
+
+ if (static_cast<bool>(m_routablePrefixesData)) {
+ BOOST_ASSERT(AUTOCONFIG_PREFIX.isPrefixOf(LOCALHOP_ROUTABLE_PREFIXES));
+ m_face.setInterestFilter(LOCALHOP_ROUTABLE_PREFIXES,
+ bind(&NdnAutoconfigServer::onRoutablePrefixesInterest,
+ this, _1, _2));
+ }
+ }
+
+ void
+ run()
+ {
+ m_face.registerPrefix(AUTOCONFIG_PREFIX,
+ bind(&NdnAutoconfigServer::afterPrefixRegistered, this),
+ bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
+
m_face.processEvents();
}
private:
- ndn::Face m_face;
- KeyChain m_keyChain;
- std::string m_faceMgmtUri;
+ Face m_face;
+ shared_ptr<Data> m_hubData;
+ shared_ptr<Data> m_routablePrefixesData;
};
int
main(int argc, char** argv)
{
- int opt;
const char* programName = argv[0];
- while ((opt = getopt(argc, argv, "hV")) != -1) {
+ PrefixCollection routablePrefixes;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "hVp:")) != -1) {
switch (opt) {
case 'h':
usage(programName);
@@ -103,6 +185,9 @@
case 'V':
std::cout << NFD_VERSION_BUILD_STRING << std::endl;
return 0;
+ case 'p':
+ routablePrefixes.add(Name(optarg));
+ break;
default:
usage(programName);
return 1;
@@ -113,11 +198,12 @@
usage(programName);
return 1;
}
- // get the configured face management uri
- NdnAutoconfigServer producer(argv[optind]);
+
+ std::string hubFaceUri = argv[optind];
+ NdnAutoconfigServer instance(hubFaceUri, routablePrefixes);
try {
- producer.listen();
+ instance.run();
}
catch (const std::exception& error) {
std::cerr << "ERROR: " << error.what() << std::endl;
@@ -125,3 +211,11 @@
}
return 0;
}
+
+} // namespace ndn
+
+int
+main(int argc, char** argv)
+{
+ return ndn::main(argc, argv);
+}