face: move packet encoding to Impl class
Practical limit of packet size is now enforced on encoded
NDNLPv2 packets instead of network-layer packets.
If a packet exceeds size limit, the face throws a
Face::OversizedPacketError exception. Since packet encoding may
be asynchronous, this exception could be thrown by
Face::processEvents instead of Face::expressInterest and
Face::put.
refs #4228
Change-Id: Ib68cf80b3b8967fdd0ba040bd8ee595a0eff740e
diff --git a/src/face.cpp b/src/face.cpp
index 1add5db..8e59ce9 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -30,9 +30,9 @@
// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
-// A callback scheduled through io.post and io.dispatch may be invoked after the face
-// is destructed. To prevent this situation, these macros captures Face::m_impl as weak_ptr,
-// and skips callback execution if the face has been destructed.
+// A callback scheduled through io.post and io.dispatch may be invoked after the face is destructed.
+// To prevent this situation, use these macros to capture Face::m_impl as weak_ptr and skip callback
+// execution if the face has been destructed.
#define IO_CAPTURE_WEAK_IMPL(OP) \
{ \
weak_ptr<Impl> implWeak(m_impl); \
@@ -46,53 +46,63 @@
namespace ndn {
+Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
+ : Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
+ name.toUri() + " encodes into " + to_string(wireSize) + " octets, "
+ "exceeding the implementation limit of " + to_string(MAX_NDN_PACKET_SIZE) + " octets")
+ , pktType(pktType)
+ , name(name)
+ , wireSize(wireSize)
+{
+}
+
Face::Face(shared_ptr<Transport> transport)
- : m_internalIoService(new boost::asio::io_service())
+ : m_internalIoService(make_unique<boost::asio::io_service>())
, m_ioService(*m_internalIoService)
- , m_internalKeyChain(new KeyChain())
+ , m_internalKeyChain(make_unique<KeyChain>())
, m_impl(make_shared<Impl>(*this))
{
- construct(transport, *m_internalKeyChain);
+ construct(std::move(transport), *m_internalKeyChain);
}
Face::Face(boost::asio::io_service& ioService)
: m_ioService(ioService)
- , m_internalKeyChain(new KeyChain())
+ , m_internalKeyChain(make_unique<KeyChain>())
, m_impl(make_shared<Impl>(*this))
{
construct(nullptr, *m_internalKeyChain);
}
Face::Face(const std::string& host, const std::string& port)
- : m_internalIoService(new boost::asio::io_service())
+ : m_internalIoService(make_unique<boost::asio::io_service>())
, m_ioService(*m_internalIoService)
- , m_internalKeyChain(new KeyChain())
+ , m_internalKeyChain(make_unique<KeyChain>())
, m_impl(make_shared<Impl>(*this))
{
construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
}
Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
- : m_internalIoService(new boost::asio::io_service())
+ : m_internalIoService(make_unique<boost::asio::io_service>())
, m_ioService(*m_internalIoService)
, m_impl(make_shared<Impl>(*this))
{
- construct(transport, keyChain);
+ construct(std::move(transport), keyChain);
}
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
: m_ioService(ioService)
- , m_internalKeyChain(new KeyChain())
+ , m_internalKeyChain(make_unique<KeyChain>())
, m_impl(make_shared<Impl>(*this))
{
- construct(transport, *m_internalKeyChain);
+ construct(std::move(transport), *m_internalKeyChain);
}
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
: m_ioService(ioService)
, m_impl(make_shared<Impl>(*this))
{
- construct(transport, keyChain);
+ construct(std::move(transport), keyChain);
}
shared_ptr<Transport>
@@ -147,9 +157,9 @@
transport = makeDefaultTransport();
}
BOOST_ASSERT(transport != nullptr);
- m_transport = transport;
+ m_transport = std::move(transport);
- m_nfdController.reset(new nfd::Controller(*this, keyChain));
+ m_nfdController = make_unique<nfd::Controller>(*this, keyChain);
IO_CAPTURE_WEAK_IMPL(post) {
impl->ensureConnected(false);
@@ -170,20 +180,15 @@
const NackCallback& afterNacked,
const TimeoutCallback& afterTimeout)
{
- shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
+ shared_ptr<Interest> interest2 = make_shared<Interest>(interest);
+ interest2->getNonce();
+ NDN_LOG_DEBUG("<I " << *interest2);
- // Use `interestToExpress` to avoid wire format creation for the original Interest
- if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE) {
- BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
- }
- NDN_LOG_DEBUG("<I " << *interestToExpress); // interestToExpress is guaranteed to have nonce
-
- // If the same ioService thread, dispatch directly calls the method
IO_CAPTURE_WEAK_IMPL(dispatch) {
- impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
+ impl->asyncExpressInterest(interest2, afterSatisfied, afterNacked, afterTimeout);
} IO_CAPTURE_WEAK_IMPL_END
- return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
+ return reinterpret_cast<const PendingInterestId*>(interest2.get());
}
void
@@ -209,60 +214,20 @@
}
void
-Face::put(const Data& data)
+Face::put(Data data)
{
- Block wire = data.wireEncode();
-
- lp::Packet packet;
- bool hasLpFields = false;
-
- shared_ptr<lp::CachePolicyTag> cachePolicyTag = data.getTag<lp::CachePolicyTag>();
- if (cachePolicyTag != nullptr) {
- packet.add<lp::CachePolicyField>(*cachePolicyTag);
- hasLpFields = true;
- }
-
- shared_ptr<lp::CongestionMarkTag> congestionMarkTag = data.getTag<lp::CongestionMarkTag>();
- if (congestionMarkTag != nullptr) {
- packet.add<lp::CongestionMarkField>(*congestionMarkTag);
- hasLpFields = true;
- }
-
- if (hasLpFields) {
- packet.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
- wire = packet.wireEncode();
- }
-
- if (wire.size() > MAX_NDN_PACKET_SIZE)
- BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
-
NDN_LOG_DEBUG("<D " << data.getName());
IO_CAPTURE_WEAK_IMPL(dispatch) {
- impl->asyncSend(wire);
+ impl->asyncPutData(data);
} IO_CAPTURE_WEAK_IMPL_END
}
void
-Face::put(const lp::Nack& nack)
+Face::put(lp::Nack nack)
{
- lp::Packet packet;
- packet.add<lp::NackField>(nack.getHeader());
- const Block& interestWire = nack.getInterest().wireEncode();
- packet.add<lp::FragmentField>(std::make_pair(interestWire.begin(), interestWire.end()));
-
- shared_ptr<lp::CongestionMarkTag> congestionMarkTag = nack.getTag<lp::CongestionMarkTag>();
- if (congestionMarkTag != nullptr) {
- packet.add<lp::CongestionMarkField>(*congestionMarkTag);
- }
-
- Block wire = packet.wireEncode();
-
- if (wire.size() > MAX_NDN_PACKET_SIZE)
- BOOST_THROW_EXCEPTION(Error("Nack size exceeds maximum limit"));
-
NDN_LOG_DEBUG("<N " << nack.getInterest() << '~' << nack.getHeader().getReason());
IO_CAPTURE_WEAK_IMPL(dispatch) {
- impl->asyncSend(wire);
+ impl->asyncPutNack(nack);
} IO_CAPTURE_WEAK_IMPL_END
}