aa9e3b2148
Change-Id: Ibf5ee5119d12d60d382b0acef8dfd08277c18fcb
227 lines
6.0 KiB
C++
227 lines
6.0 KiB
C++
/* -*- 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "transport.hpp"
|
|
#include "face.hpp"
|
|
|
|
namespace nfd::face {
|
|
|
|
NFD_LOG_INIT(Transport);
|
|
|
|
std::ostream&
|
|
operator<<(std::ostream& os, TransportState state)
|
|
{
|
|
switch (state) {
|
|
case TransportState::UP:
|
|
return os << "UP";
|
|
case TransportState::DOWN:
|
|
return os << "DOWN";
|
|
case TransportState::CLOSING:
|
|
return os << "CLOSING";
|
|
case TransportState::FAILED:
|
|
return os << "FAILED";
|
|
case TransportState::CLOSED:
|
|
return os << "CLOSED";
|
|
default:
|
|
return os << "NONE";
|
|
}
|
|
}
|
|
|
|
Transport::Transport() = default;
|
|
|
|
Transport::~Transport() = default;
|
|
|
|
void
|
|
Transport::setFaceAndLinkService(Face& face, LinkService& service) noexcept
|
|
{
|
|
BOOST_ASSERT(m_face == nullptr);
|
|
BOOST_ASSERT(m_service == nullptr);
|
|
|
|
m_face = &face;
|
|
m_service = &service;
|
|
}
|
|
|
|
void
|
|
Transport::close()
|
|
{
|
|
if (m_state != TransportState::UP && m_state != TransportState::DOWN) {
|
|
return;
|
|
}
|
|
|
|
this->setState(TransportState::CLOSING);
|
|
this->doClose();
|
|
// warning: don't access any members after this:
|
|
// the Transport may be deallocated if doClose changes state to CLOSED
|
|
}
|
|
|
|
void
|
|
Transport::send(const Block& packet)
|
|
{
|
|
BOOST_ASSERT(packet.isValid());
|
|
BOOST_ASSERT(this->getMtu() == MTU_UNLIMITED ||
|
|
packet.size() <= static_cast<size_t>(this->getMtu()));
|
|
|
|
TransportState state = this->getState();
|
|
if (state != TransportState::UP && state != TransportState::DOWN) {
|
|
NFD_LOG_FACE_TRACE("send ignored in " << state << " state");
|
|
return;
|
|
}
|
|
|
|
if (state == TransportState::UP) {
|
|
++this->nOutPackets;
|
|
this->nOutBytes += packet.size();
|
|
}
|
|
|
|
this->doSend(packet);
|
|
}
|
|
|
|
void
|
|
Transport::receive(const Block& packet, const EndpointId& endpoint)
|
|
{
|
|
BOOST_ASSERT(packet.isValid());
|
|
BOOST_ASSERT(this->getMtu() == MTU_UNLIMITED ||
|
|
packet.size() <= static_cast<size_t>(this->getMtu()));
|
|
|
|
++this->nInPackets;
|
|
this->nInBytes += packet.size();
|
|
|
|
m_service->receivePacket(packet, endpoint);
|
|
}
|
|
|
|
void
|
|
Transport::setMtu(ssize_t mtu) noexcept
|
|
{
|
|
BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu >= 0);
|
|
|
|
if (mtu == m_mtu) {
|
|
return;
|
|
}
|
|
|
|
if (m_mtu != MTU_INVALID) {
|
|
NFD_LOG_FACE_INFO("setMtu " << m_mtu << " -> " << mtu);
|
|
}
|
|
|
|
m_mtu = mtu;
|
|
}
|
|
|
|
bool
|
|
Transport::canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const
|
|
{
|
|
// not changing, or setting initial persistency in subclass constructor
|
|
if (m_persistency == newPersistency || m_persistency == ndn::nfd::FACE_PERSISTENCY_NONE) {
|
|
return true;
|
|
}
|
|
|
|
if (newPersistency == ndn::nfd::FACE_PERSISTENCY_NONE) {
|
|
NFD_LOG_FACE_TRACE("cannot change persistency to NONE");
|
|
return false;
|
|
}
|
|
|
|
return this->canChangePersistencyToImpl(newPersistency);
|
|
}
|
|
|
|
bool
|
|
Transport::canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
void
|
|
Transport::afterChangePersistency(ndn::nfd::FacePersistency oldPersistency)
|
|
{
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
std::ostream&
|
|
operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh)
|
|
{
|
|
const Transport& transport = flh.obj;
|
|
const Face* face = transport.getFace();
|
|
FaceId faceId = face == nullptr ? INVALID_FACEID : face->getId();
|
|
|
|
os << "[id=" << faceId << ",local=" << transport.getLocalUri()
|
|
<< ",remote=" << transport.getRemoteUri() << "] ";
|
|
return os;
|
|
}
|
|
|
|
} // namespace nfd::face
|