tools: Process auto-registration for faces that existed prior to start of nfd-autoreg
Change-Id: I3848f1a20a0d816258759f95d427cf91cb3b9713
Refs: #1863
diff --git a/tools/nfd-autoreg.cpp b/tools/nfd-autoreg.cpp
index e85cdff..5164f5d 100644
--- a/tools/nfd-autoreg.cpp
+++ b/tools/nfd-autoreg.cpp
@@ -28,6 +28,8 @@
#include <ndn-cxx/management/nfd-controller.hpp>
#include <ndn-cxx/management/nfd-face-monitor.hpp>
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
@@ -81,13 +83,11 @@
}
/**
- * \return true if uri is blacklisted
+ * \return true if address is blacklisted
*/
bool
- isBlacklisted(const FaceUri& uri)
+ isBlacklisted(const boost::asio::ip::address& address)
{
- boost::asio::ip::address address = boost::asio::ip::address::from_string(uri.getHost());
-
for (std::vector<Network>::const_iterator network = m_blackList.begin();
network != m_blackList.end();
++network)
@@ -100,13 +100,11 @@
}
/**
- * \return true if uri is whitelisted
+ * \return true if address is whitelisted
*/
bool
- isWhitelisted(const FaceUri& uri)
+ isWhitelisted(const boost::asio::ip::address& address)
{
- boost::asio::ip::address address = boost::asio::ip::address::from_string(uri.getHost());
-
for (std::vector<Network>::const_iterator network = m_whiteList.begin();
network != m_whiteList.end();
++network)
@@ -139,6 +137,25 @@
}
void
+ registerPrefixesIfNeeded(uint64_t faceId, const FaceUri& uri, bool isOnDemand)
+ {
+ if (hasAllowedSchema(uri)) {
+ boost::system::error_code ec;
+ boost::asio::ip::address address = boost::asio::ip::address::from_string(uri.getHost(), ec);
+
+ if (!address.is_multicast()) {
+ // register all-face prefixes
+ registerPrefixesForFace(faceId, m_allFacesPrefixes);
+
+ // register autoreg prefixes if new face is on-demand and not blacklisted and whitelisted
+ if (isOnDemand && !isBlacklisted(address) && isWhitelisted(address)) {
+ registerPrefixesForFace(faceId, m_autoregPrefixes);
+ }
+ }
+ }
+ }
+
+ void
onNotification(const FaceEventNotification& notification)
{
if (notification.getKind() == FACE_EVENT_CREATED &&
@@ -146,17 +163,8 @@
{
std::cerr << "PROCESSING: " << notification << std::endl;
- FaceUri uri(notification.getRemoteUri());
-
- if (hasAllowedSchema(uri)) {
- // register all-face prefixes
- registerPrefixesForFace(notification.getFaceId(), m_allFacesPrefixes);
-
- // register autoreg prefixes if new face is on-demand and not blacklisted and whitelisted
- if (notification.isOnDemand() && !isBlacklisted(uri) && isWhitelisted(uri)) {
- registerPrefixesForFace(notification.getFaceId(), m_autoregPrefixes);
- }
- }
+ registerPrefixesIfNeeded(notification.getFaceId(), FaceUri(notification.getRemoteUri()),
+ notification.isOnDemand());
}
else
{
@@ -229,6 +237,68 @@
m_face.processEvents();
}
+
+ void
+ fetchFaceStatusSegments(const Data& data, const shared_ptr<ndn::OBufferStream>& buffer)
+ {
+ buffer->write(reinterpret_cast<const char*>(data.getContent().value()),
+ data.getContent().value_size());
+
+ uint64_t currentSegment = data.getName().get(-1).toSegment();
+
+ const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
+ if (finalBlockId.empty() ||
+ finalBlockId.toSegment() > currentSegment)
+ {
+ m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
+ bind(&AutoregServer::fetchFaceStatusSegments, this, _2, buffer),
+ ndn::OnTimeout());
+ }
+ else
+ {
+ return processFaceStatusDataset(buffer);
+ }
+ }
+
+ void
+ startFetchingFaceStatusDataset()
+ {
+ shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
+
+ Interest interest("/localhost/nfd/faces/list");
+ interest.setChildSelector(1);
+ interest.setMustBeFresh(true);
+
+ m_face.expressInterest(interest,
+ bind(&AutoregServer::fetchFaceStatusSegments, this, _2, buffer),
+ ndn::OnTimeout());
+ }
+
+ void
+ processFaceStatusDataset(const shared_ptr<ndn::OBufferStream>& buffer)
+ {
+ ndn::ConstBufferPtr buf = buffer->buf();
+ std::vector<uint64_t> multicastFaces;
+
+ size_t offset = 0;
+ while (offset < buf->size())
+ {
+ Block block;
+ bool ok = Block::fromBuffer(buf, offset, block);
+ if (!ok)
+ {
+ std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
+ break;
+ }
+
+ offset += block.size();
+
+ nfd::FaceStatus faceStatus(block);
+ registerPrefixesIfNeeded(faceStatus.getFaceId(), FaceUri(faceStatus.getRemoteUri()),
+ faceStatus.isOnDemand());
+ }
+ }
+
int
main(int argc, char* argv[])
{
@@ -292,6 +362,7 @@
try
{
+ startFetchingFaceStatusDataset();
startProcessing();
}
catch (std::exception& e)