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();
  }
Esempio n. 3
0
void
FaceIdFetcher::startGetFaceId(const FaceUri& faceUri)
{
  faceUri.canonize(bind(&FaceIdFetcher::onCanonizeSuccess, this, _1),
                   bind(&FaceIdFetcher::onCanonizeFailure, this, _1),
                   m_face.getIoService(), time::seconds(4));
}
Esempio n. 4
0
FindFace::Code
FindFace::execute(const FaceUri& faceUri, bool allowMulti)
{
  FaceQueryFilter filter;
  filter.setRemoteUri(faceUri.toString());
  return this->execute(filter, allowMulti);
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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"));
}
Esempio n. 7
0
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));
}
Esempio n. 8
0
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);
  }
Esempio n. 10
0
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));
}
Esempio n. 11
0
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);
    }
}
Esempio n. 14
0
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;
  }
}