virtual void canonize(const FaceUri& faceUri, const FaceUri::CanonizeSuccessCallback& onSuccess, const FaceUri::CanonizeFailureCallback& onFailure, boost::asio::io_service& io, const time::nanoseconds& timeout) const { if (this->isCanonical(faceUri)) { onSuccess(faceUri); return; } dns::AddressSelector addressSelector; if (faceUri.getScheme() == m_v4Scheme) { addressSelector = dns::Ipv4Only(); } else if (faceUri.getScheme() == m_v6Scheme) { addressSelector = dns::Ipv6Only(); } else { BOOST_ASSERT(faceUri.getScheme() == m_baseScheme); addressSelector = dns::AnyAddress(); } // make a copy because caller may modify faceUri shared_ptr<FaceUri> uri = make_shared<FaceUri>(faceUri); dns::asyncResolve(faceUri.getHost(), bind(&IpHostCanonizeProvider<Protocol>::onDnsSuccess, this, uri, onSuccess, onFailure, _1), bind(&IpHostCanonizeProvider<Protocol>::onDnsFailure, this, uri, onFailure, _1), io, addressSelector, timeout); }
virtual bool isCanonical(const FaceUri& faceUri) const { if (!faceUri.getPort().empty()) { return false; } if (!faceUri.getPath().empty()) { return false; } ethernet::Address addr = ethernet::Address::fromString(faceUri.getHost()); return addr.toString() == faceUri.getHost(); }
void FaceIdFetcher::startGetFaceId(const FaceUri& faceUri) { faceUri.canonize(bind(&FaceIdFetcher::onCanonizeSuccess, this, _1), bind(&FaceIdFetcher::onCanonizeFailure, this, _1), m_face.getIoService(), time::seconds(4)); }
FindFace::Code FindFace::execute(const FaceUri& faceUri, bool allowMulti) { FaceQueryFilter filter; filter.setRemoteUri(faceUri.toString()); return this->execute(filter, allowMulti); }
optional<FaceUri> FindFace::canonize(const std::string& fieldName, const FaceUri& input) { if (!FaceUri::canCanonize(input.getScheme())) { NDN_LOG_DEBUG("Using " << fieldName << '=' << input << " without canonization"); return input; } optional<FaceUri> result; input.canonize( [&result] (const FaceUri& canonicalUri) { result = canonicalUri; }, [this, fieldName] (const std::string& errorReason) { m_errorReason = "Error during " + fieldName + " FaceUri canonization: " + errorReason; }, m_ctx.face.getIoService(), m_ctx.getTimeout()); m_ctx.face.processEvents(); return result; }
void FaceIdFetcher::startFaceCreate(const FaceUri& canonicalUri) { ndn::nfd::ControlParameters parameters; parameters.setUri(canonicalUri.toString()); m_controller.start<ndn::nfd::FaceCreateCommand>(parameters, [this] (const ndn::nfd::ControlParameters& result) { succeed(result.getFaceId()); }, bind(&FaceIdFetcher::onFaceCreateError, this, _1, "Face creation failed")); }
void UdpFactory::createFace(const FaceUri& uri, ndn::nfd::FacePersistency persistency, const FaceCreatedCallback& onCreated, const FaceConnectFailedCallback& onConnectFailed) { if (persistency == ndn::nfd::FacePersistency::FACE_PERSISTENCY_ON_DEMAND) { BOOST_THROW_EXCEPTION(Error("UdpFactory::createFace does not support creating on-demand face")); } BOOST_ASSERT(uri.isCanonical()); boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost()); udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort())); if (endpoint.address().is_multicast()) { onConnectFailed("The provided address is multicast. Please use createMulticastFace method"); return; } if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end()) { onConnectFailed("Requested endpoint is prohibited " "(reserved by this NFD or disallowed by face management protocol)"); return; } // very simple logic for now for (ChannelMap::iterator channel = m_channels.begin(); channel != m_channels.end(); ++channel) { if ((channel->first.address().is_v4() && endpoint.address().is_v4()) || (channel->first.address().is_v6() && endpoint.address().is_v6())) { channel->second->connect(endpoint, persistency, onCreated, onConnectFailed); return; } } onConnectFailed("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint)); }
void FaceIdFetcher::start(ndn::Face& face, ndn::nfd::Controller& controller, const std::string& input, bool allowCreate, const SuccessCallback& onSucceed, const FailureCallback& onFail) { // 1. Try parse input as FaceId, if input is FaceId, succeed with parsed FaceId // 2. Try parse input as FaceUri, if input is not FaceUri, fail // 3. Canonize faceUri // 4. If canonization fails, fail // 5. Query for face // 6. If query succeeds and finds a face, succeed with found FaceId // 7. Create face // 8. If face creation succeeds, succeed with created FaceId // 9. Fail boost::regex e("^[a-z0-9]+\\:.*"); if (!boost::regex_match(input, e)) { try { uint32_t faceId = boost::lexical_cast<uint32_t>(input); onSucceed(faceId); return; } catch (const boost::bad_lexical_cast&) { onFail("No valid faceId or faceUri is provided"); return; } } else { FaceUri faceUri; if (!faceUri.parse(input)) { onFail("FaceUri parse failed"); return; } auto fetcher = new FaceIdFetcher(std::ref(face), std::ref(controller), allowCreate, onSucceed, onFail); fetcher->startGetFaceId(faceUri); } }
virtual void canonize(const FaceUri& faceUri, const FaceUri::CanonizeSuccessCallback& onSuccess, const FaceUri::CanonizeFailureCallback& onFailure, boost::asio::io_service& io, const time::nanoseconds& timeout) const { ethernet::Address addr = ethernet::Address::fromString(faceUri.getHost()); if (addr.isNull()) { onFailure("cannot parse address"); return; } FaceUri canonicalUri(addr); BOOST_ASSERT(canonicalUri.isCanonical()); onSuccess(canonicalUri); }
void FaceIdFetcher::onCanonizeSuccess(const FaceUri& canonicalUri) { ndn::Name queryName("/localhost/nfd/faces/query"); ndn::nfd::FaceQueryFilter queryFilter; queryFilter.setRemoteUri(canonicalUri.toString()); queryName.append(queryFilter.wireEncode()); ndn::Interest interestPacket(queryName); interestPacket.setMustBeFresh(true); interestPacket.setInterestLifetime(time::milliseconds(4000)); auto interest = std::make_shared<ndn::Interest>(interestPacket); ndn::util::SegmentFetcher::fetch( m_face, *interest, m_validator, bind(&FaceIdFetcher::onQuerySuccess, this, _1, canonicalUri), bind(&FaceIdFetcher::onQueryFailure, this, _1, canonicalUri)); }
void TcpFactory::createFace(const FaceUri& uri, const FaceCreatedCallback& onCreated, const FaceConnectFailedCallback& onConnectFailed) { resolver::AddressSelector addressSelector = resolver::AnyAddress(); if (uri.getScheme() == "tcp4") addressSelector = resolver::Ipv4Address(); else if (uri.getScheme() == "tcp6") addressSelector = resolver::Ipv6Address(); if (!uri.getPath().empty() && uri.getPath() != "/") { onConnectFailed("Invalid URI"); } TcpResolver::asyncResolve(uri.getHost(), uri.getPort().empty() ? m_defaultPort : uri.getPort(), bind(&TcpFactory::continueCreateFaceAfterResolve, this, _1, onCreated, onConnectFailed), onConnectFailed, addressSelector); }
virtual bool isCanonical(const FaceUri& faceUri) const { if (faceUri.getPort().empty()) { return false; } if (!faceUri.getPath().empty()) { return false; } boost::system::error_code ec; boost::asio::ip::address addr; if (faceUri.getScheme() == m_v4Scheme) { addr = boost::asio::ip::address_v4::from_string(faceUri.getHost(), ec); } else if (faceUri.getScheme() == m_v6Scheme) { addr = boost::asio::ip::address_v6::from_string(faceUri.getHost(), ec); } else { return false; } return !static_cast<bool>(ec) && addr.to_string() == faceUri.getHost() && this->checkAddress(addr).first; }
void FaceManager::createFace(const Interest& request, ControlParameters& parameters) { const Name& requestName = request.getName(); ndn::nfd::FaceCreateCommand command; if (!validateParameters(command, parameters)) { sendResponse(requestName, 400, "Malformed command"); NFD_LOG_TRACE("invalid control parameters URI"); return; } FaceUri uri; if (!uri.parse(parameters.getUri())) { sendResponse(requestName, 400, "Malformed command"); NFD_LOG_TRACE("failed to parse URI"); return; } if (!uri.isCanonical()) { sendResponse(requestName, 400, "Non-canonical URI"); NFD_LOG_TRACE("received non-canonical URI"); return; } FactoryMap::iterator factory = m_factories.find(uri.getScheme()); if (factory == m_factories.end()) { sendResponse(requestName, 501, "Unsupported protocol"); return; } try { factory->second->createFace(uri, bind(&FaceManager::onCreated, this, requestName, parameters, _1), bind(&FaceManager::onConnectFailed, this, requestName, _1)); } catch (const std::runtime_error& error) { std::string errorMessage = "NFD error: "; errorMessage += error.what(); NFD_LOG_ERROR(errorMessage); sendResponse(requestName, 500, errorMessage); } catch (const std::logic_error& error) { std::string errorMessage = "NFD error: "; errorMessage += error.what(); NFD_LOG_ERROR(errorMessage); sendResponse(requestName, 500, errorMessage); } }
void FaceManager::createFace(const ControlParameters& parameters, const ndn::mgmt::CommandContinuation& done) { FaceUri remoteUri; if (!remoteUri.parse(parameters.getUri())) { NFD_LOG_TRACE("failed to parse remote URI: " << parameters.getUri()); done(ControlResponse(400, "Malformed command")); return; } if (!remoteUri.isCanonical()) { NFD_LOG_TRACE("received non-canonical remote URI: " << remoteUri.toString()); done(ControlResponse(400, "Non-canonical remote URI")); return; } optional<FaceUri> localUri; if (parameters.hasLocalUri()) { localUri = FaceUri{}; if (!localUri->parse(parameters.getLocalUri())) { NFD_LOG_TRACE("failed to parse local URI: " << parameters.getLocalUri()); done(ControlResponse(400, "Malformed command")); return; } if (!localUri->isCanonical()) { NFD_LOG_TRACE("received non-canonical local URI: " << localUri->toString()); done(ControlResponse(400, "Non-canonical local URI")); return; } } face::ProtocolFactory* factory = m_faceSystem.getFactoryByScheme(remoteUri.getScheme()); if (factory == nullptr) { NFD_LOG_TRACE("received create request for unsupported protocol: " << remoteUri.getScheme()); done(ControlResponse(406, "Unsupported protocol")); return; } face::FaceParams faceParams; faceParams.persistency = parameters.getFacePersistency(); if (parameters.hasBaseCongestionMarkingInterval()) { faceParams.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval(); } if (parameters.hasDefaultCongestionThreshold()) { faceParams.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold(); } if (parameters.hasMtu()) { faceParams.mtu = parameters.getMtu(); } faceParams.wantLocalFields = parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) && parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED); faceParams.wantLpReliability = parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) && parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED); if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) { faceParams.wantCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED); } try { factory->createFace({remoteUri, localUri, faceParams}, [this, parameters, done] (const auto& face) { this->afterCreateFaceSuccess(face, parameters, done); }, [done] (uint32_t status, const std::string& reason) { NFD_LOG_DEBUG("Face creation failed: " << reason); done(ControlResponse(status, reason)); }); } catch (const std::runtime_error& error) { NFD_LOG_ERROR("Face creation failed: " << error.what()); done(ControlResponse(500, "Face creation failed due to internal error")); return; } catch (const std::logic_error& error) { NFD_LOG_ERROR("Face creation failed: " << error.what()); done(ControlResponse(500, "Face creation failed due to internal error")); return; } }