예제 #1
0
파일: udp-face.cpp 프로젝트: AaronTien/NFD
void
UdpFace::closeIfIdle()
{
  // Face can be switched from on-demand to non-on-demand mode
  // (non-on-demand -> on-demand transition is not allowed)
  if (this->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
    if (!hasBeenUsedRecently()) {
      NFD_LOG_FACE_INFO("Closing for inactivity");
      close();

      // #1718 manual test: uncomment, run NFD in valgrind, send in a UDP packet
      //                    expect read-after-free error and crash
      // getGlobalIoService().post([this] {
      //   NFD_LOG_FACE_ERROR("Remaining references: " << this->shared_from_this().use_count());
      // });
    }
    else {
      resetRecentUsage();

      m_lastIdleCheck = time::steady_clock::now();
      m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, bind(&UdpFace::closeIfIdle, this));
    }
  }
  // else do nothing and do not reschedule the event
}
예제 #2
0
WebSocketTransport::WebSocketTransport(websocketpp::connection_hdl hdl,
                                       websocket::Server& server,
                                       time::milliseconds pingInterval)
  : m_handle(hdl)
  , m_server(server)
  , m_pingInterval(pingInterval)
{
  const auto& sock = m_server.get_con_from_hdl(hdl)->get_socket();
  this->setLocalUri(FaceUri(sock.local_endpoint(), "ws"));
  this->setRemoteUri(FaceUri(sock.remote_endpoint(), "wsclient"));

  if (isLoopback(sock.local_endpoint().address()) &&
      isLoopback(sock.remote_endpoint().address())) {
    this->setScope(ndn::nfd::FACE_SCOPE_LOCAL);
  }
  else {
    this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
  }

  this->setPersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
  this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
  this->setMtu(MTU_UNLIMITED);

  this->schedulePing();

  NFD_LOG_FACE_INFO("Creating transport");
}
예제 #3
0
void
UnicastUdpTransport::scheduleClosureWhenIdle()
{
  m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, [this] {
    if (!hasBeenUsedRecently()) {
      NFD_LOG_FACE_INFO("Closing due to inactivity");
      this->close();
    }
    else {
      resetRecentUsage();
      scheduleClosureWhenIdle();
    }
  });
  setExpirationTime(time::steady_clock::now() + m_idleTimeout);
}
예제 #4
0
void
Transport::setPersistency(ndn::nfd::FacePersistency newPersistency)
{
  BOOST_ASSERT(canChangePersistencyTo(newPersistency));

  if (m_persistency == newPersistency) {
    return;
  }

  auto oldPersistency = m_persistency;
  m_persistency = newPersistency;

  if (oldPersistency != ndn::nfd::FACE_PERSISTENCY_NONE) {
    NFD_LOG_FACE_INFO("setPersistency " << oldPersistency << " -> " << newPersistency);
    this->afterChangePersistency(oldPersistency);
  }
}
예제 #5
0
TcpTransport::TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency)
  : StreamTransport(std::move(socket))
  , m_remoteEndpoint(m_socket.remote_endpoint())
  , m_nextReconnectWait(s_initialReconnectWait)
{
  this->setLocalUri(FaceUri(m_socket.local_endpoint()));
  this->setRemoteUri(FaceUri(m_socket.remote_endpoint()));

  if (m_socket.local_endpoint().address().is_loopback() &&
      m_socket.remote_endpoint().address().is_loopback())
    this->setScope(ndn::nfd::FACE_SCOPE_LOCAL);
  else
    this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);

  this->setPersistency(persistency);
  this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
  this->setMtu(MTU_UNLIMITED);

  NFD_LOG_FACE_INFO("Creating transport");
}
예제 #6
0
UnicastUdpTransport::UnicastUdpTransport(protocol::socket&& socket,
                                         ndn::nfd::FacePersistency persistency,
                                         time::nanoseconds idleTimeout)
  : DatagramTransport(std::move(socket))
  , m_idleTimeout(idleTimeout)
{
  this->setLocalUri(FaceUri(m_socket.local_endpoint()));
  this->setRemoteUri(FaceUri(m_socket.remote_endpoint()));
  this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
  this->setPersistency(persistency);
  this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
  this->setMtu(udp::computeMtu(m_socket.local_endpoint()));

  NFD_LOG_FACE_INFO("Creating transport");

#ifdef __linux__
  //
  // By default, Linux does path MTU discovery on IPv4 sockets,
  // and sets the DF (Don't Fragment) flag on datagrams smaller
  // than the interface MTU. However this does not work for us,
  // because we cannot properly respond to ICMP "packet too big"
  // messages by fragmenting the packet at the application level,
  // since we want to rely on IP for fragmentation and reassembly.
  //
  // Therefore, we disable PMTU discovery, which prevents the kernel
  // from setting the DF flag on outgoing datagrams, and thus allows
  // routers along the path to perform fragmentation as needed.
  //
  const int value = IP_PMTUDISC_DONT;
  if (::setsockopt(m_socket.native_handle(), IPPROTO_IP,
                   IP_MTU_DISCOVER, &value, sizeof(value)) < 0) {
    NFD_LOG_FACE_WARN("Failed to disable path MTU discovery: " << std::strerror(errno));
  }
#endif

  if (getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND &&
      m_idleTimeout > time::nanoseconds::zero()) {
    scheduleClosureWhenIdle();
  }
}
예제 #7
0
void
Transport::setState(TransportState newState)
{
  if (m_state == newState) {
    return;
  }

  bool isValid = false;
  switch (m_state) {
    case TransportState::UP:
      isValid = newState == TransportState::DOWN ||
                newState == TransportState::CLOSING ||
                newState == TransportState::FAILED;
      break;
    case TransportState::DOWN:
      isValid = newState == TransportState::UP ||
                newState == TransportState::CLOSING ||
                newState == TransportState::FAILED;
      break;
    case TransportState::CLOSING:
    case TransportState::FAILED:
      isValid = newState == TransportState::CLOSED;
      break;
    default:
      break;
  }

  if (!isValid) {
    NDN_THROW(std::runtime_error("Invalid state transition"));
  }

  NFD_LOG_FACE_INFO("setState " << m_state << " -> " << newState);

  TransportState oldState = m_state;
  m_state = newState;
  afterStateChange(oldState, newState);
  // warning: don't access any members after this:
  // the Transport may be deallocated in the signal handler if newState is CLOSED
}