void TcpTransport::reconnect() { NFD_LOG_FACE_TRACE(__func__); if (getState() == TransportState::CLOSING || getState() == TransportState::FAILED || getState() == TransportState::CLOSED) { // transport is shutting down, don't attempt to reconnect return; } BOOST_ASSERT(getPersistency() == ndn::nfd::FACE_PERSISTENCY_PERMANENT); BOOST_ASSERT(getState() == TransportState::DOWN); // recreate the socket m_socket = protocol::socket(m_socket.get_io_service()); this->resetReceiveBuffer(); this->resetSendQueue(); m_reconnectEvent = scheduler::schedule(m_nextReconnectWait, [this] { handleReconnectTimeout(); }); m_socket.async_connect(m_remoteEndpoint, [this] (const boost::system::error_code& error) { handleReconnect(error); }); }
void Face::copyStatusTo(FaceTraits& traits) const { traits.setFaceId(getId()) .setRemoteUri(getRemoteUri().toString()) .setLocalUri(getLocalUri().toString()) .setFaceScope(isLocal() ? ndn::nfd::FACE_SCOPE_LOCAL : ndn::nfd::FACE_SCOPE_NON_LOCAL) .setFacePersistency(getPersistency()) .setLinkType(isMultiAccess() ? ndn::nfd::LINK_TYPE_MULTI_ACCESS : ndn::nfd::LINK_TYPE_POINT_TO_POINT); }
void UnicastUdpTransport::afterChangePersistency(ndn::nfd::FacePersistency oldPersistency) { if (getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND && m_idleTimeout > time::nanoseconds::zero()) { scheduleClosureWhenIdle(); } else { m_closeIfIdleEvent.cancel(); setExpirationTime(time::steady_clock::TimePoint::max()); } }
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(); } }
void DatagramTransport<T, U>::processErrorCode(const boost::system::error_code& error) { NFD_LOG_FACE_TRACE(__func__); if (getState() == TransportState::CLOSING || getState() == TransportState::FAILED || getState() == TransportState::CLOSED || error == boost::asio::error::operation_aborted) { // transport is shutting down, ignore any errors return; } if (getPersistency() == ndn::nfd::FACE_PERSISTENCY_PERMANENT) { NFD_LOG_FACE_DEBUG("Permanent face ignores error: " << error.message()); return; } NFD_LOG_FACE_ERROR("Send or receive operation failed: " << error.message()); this->setState(TransportState::FAILED); doClose(); }