/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2014-2022, Regents of the University of California, * Arizona Board of Regents, * Colorado State University, * University Pierre & Marie Curie, Sorbonne University, * Washington University in St. Louis, * Beijing Institute of Technology, * The University of Memphis. * * This file is part of NFD (Named Data Networking Forwarding Daemon). * See AUTHORS.md for complete list of NFD authors and contributors. * * NFD is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * NFD, e.g., in COPYING.md file. If not, see . */ #include "netdev-bound.hpp" #include "face-system.hpp" #include "common/logger.hpp" namespace nfd::face { NFD_LOG_INIT(NetdevBound); NetdevBound::NetdevBound(const ProtocolFactoryCtorParams& params, const FaceSystem& faceSystem) : m_faceSystem(faceSystem) , m_addFace(params.addFace) , m_netmon(params.netmon) { } void NetdevBound::processConfig(OptionalConfigSection configSection, FaceSystem::ConfigContext& context) { std::vector rules; if (configSection) { int ruleIndex = 0; for (const auto& [key, value] : *configSection) { if (key == "rule") { rules.push_back(parseRule(ruleIndex++, value)); } else { NDN_THROW(ConfigFile::Error("Unrecognized option face_system.netdev_bound." + key)); } } } if (context.isDryRun) { return; } ///\todo #3521 this should be verified in dry-run, but PFs won't publish their *+dev schemes /// in dry-run for (size_t i = 0; i < rules.size(); ++i) { const Rule& rule = rules[i]; for (const FaceUri& remote : rule.remotes) { std::string devScheme = remote.getScheme() + "+dev"; if (!m_faceSystem.hasFactoryForScheme(devScheme)) { NDN_THROW(RuleParseError(i, "scheme '" + devScheme + "' for " + remote.toString() + " is unavailable")); } } } NFD_LOG_DEBUG("processConfig: processed " << rules.size() << " rules"); m_rules.swap(rules); std::map> oldFaces; oldFaces.swap(m_faces); ///\todo #3521 for each face needed under m_rules: /// if it's in oldFaces, add to m_faces and remove from oldFaces; /// otherwise, create via factory and add to m_faces ///\todo #3521 close faces in oldFaces } NetdevBound::Rule NetdevBound::parseRule(int index, const ConfigSection& confRule) const { Rule rule; bool hasWhitelist = false; bool hasBlacklist = false; for (const auto& [key, value] : confRule) { if (key == "remote") { try { rule.remotes.emplace_back(value.get_value()); } catch (const FaceUri::Error&) { NDN_THROW_NESTED(RuleParseError(index, "invalid remote FaceUri")); } if (!rule.remotes.back().isCanonical()) { NDN_THROW(RuleParseError(index, "remote FaceUri is not canonical")); } } else if (key == "whitelist") { if (hasWhitelist) { NDN_THROW(RuleParseError(index, "duplicate whitelist")); } try { rule.netifPredicate.parseWhitelist(value); } catch (const ConfigFile::Error&) { NDN_THROW_NESTED(RuleParseError(index, "invalid whitelist")); } hasWhitelist = true; } else if (key == "blacklist") { if (hasBlacklist) { NDN_THROW(RuleParseError(index, "duplicate blacklist")); } try { rule.netifPredicate.parseBlacklist(value); } catch (const ConfigFile::Error&) { NDN_THROW_NESTED(RuleParseError(index, "invalid blacklist")); } hasBlacklist = true; } else { NDN_THROW(RuleParseError(index, "unrecognized option " + key)); } } if (rule.remotes.empty()) { NDN_THROW(RuleParseError(index, "remote FaceUri is missing")); } ///\todo #3521 for each remote, check that there is a factory providing scheme+dev scheme return rule; } } // namespace nfd::face