25 #include "ndn-cxx/impl/face-impl.hpp"
38 :
Error((pktType ==
'I' ?
"Interest " : pktType ==
'D' ?
"Data " :
"Nack ") +
39 name.toUri() +
" encodes into " + std::
to_string(wireSize) +
" octets, "
48 : m_internalIoCtx(make_unique<
boost::asio::io_context>())
49 , m_ioCtx(*m_internalIoCtx)
50 , m_internalKeyChain(make_unique<
KeyChain>())
52 construct(std::move(transport), *m_internalKeyChain);
57 , m_internalKeyChain(make_unique<
KeyChain>())
59 construct(
nullptr, *m_internalKeyChain);
62 Face::Face(
const std::string& host,
const std::string& port)
63 : m_internalIoCtx(make_unique<
boost::asio::io_context>())
64 , m_ioCtx(*m_internalIoCtx)
65 , m_internalKeyChain(make_unique<
KeyChain>())
67 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
71 : m_internalIoCtx(make_unique<
boost::asio::io_context>())
72 , m_ioCtx(*m_internalIoCtx)
74 construct(std::move(transport), keyChain);
77 Face::Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx)
79 , m_internalKeyChain(make_unique<
KeyChain>())
81 construct(std::move(transport), *m_internalKeyChain);
87 construct(std::move(transport), keyChain);
90 static shared_ptr<Transport>
91 makeDefaultTransport()
93 std::string transportUri;
95 const char* transportEnviron = getenv(
"NDN_CLIENT_TRANSPORT");
96 if (transportEnviron !=
nullptr) {
97 transportUri = transportEnviron;
101 transportUri = config.getParsedConfiguration().get<std::string>(
"transport",
"");
104 if (transportUri.empty()) {
110 std::string protocol = FaceUri(transportUri).getScheme();
111 if (protocol ==
"unix") {
114 else if (protocol ==
"tcp" || protocol ==
"tcp4" || protocol ==
"tcp6") {
118 NDN_THROW(ConfigFile::Error(
"Unsupported transport protocol \"" + protocol +
"\""));
121 catch (
const Transport::Error& e) {
122 NDN_THROW_NESTED(ConfigFile::Error(
"Failed to create transport: "s + e.what()));
124 catch (
const FaceUri::Error& e) {
125 NDN_THROW_NESTED(ConfigFile::Error(
"Failed to create transport: "s + e.what()));
130 Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
132 BOOST_ASSERT(m_impl ==
nullptr);
133 m_impl = make_shared<Impl>(*
this, keyChain);
135 if (transport ==
nullptr) {
136 transport = makeDefaultTransport();
137 BOOST_ASSERT(transport !=
nullptr);
139 m_transport = std::move(transport);
141 boost::asio::post(m_ioCtx, [w = m_impl->weak_from_this()] {
142 if (auto impl = w.lock(); impl != nullptr) {
143 impl->ensureConnected(false);
148 Face::~Face() =
default;
150 PendingInterestHandle
156 auto id = m_impl->m_pendingInterestTable.allocateId();
157 auto interest2 = make_shared<Interest>(interest);
158 interest2->getNonce();
160 boost::asio::post(m_ioCtx, [=, w = m_impl->weak_from_this()] {
161 if (auto impl = w.lock(); impl != nullptr) {
162 impl->expressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
170 Face::removeAllPendingInterests()
172 boost::asio::post(m_ioCtx, [w = m_impl->weak_from_this()] {
173 if (auto impl = w.lock(); impl != nullptr) {
174 impl->removeAllPendingInterests();
180 Face::getNPendingInterests()
const
182 return m_impl->m_pendingInterestTable.size();
188 boost::asio::post(m_ioCtx, [data, w = m_impl->weak_from_this()] {
189 if (auto impl = w.lock(); impl != nullptr) {
198 boost::asio::post(m_ioCtx, [nack, w = m_impl->weak_from_this()] {
199 if (auto impl = w.lock(); impl != nullptr) {
205 RegisteredPrefixHandle
210 return setInterestFilter(filter, onInterest,
nullptr, onFailure, signingInfo, flags);
222 auto id = m_impl->registerPrefix(filter.
getPrefix(), onSuccess, onFailure, flags, options,
230 auto id = m_impl->m_interestFilterTable.allocateId();
232 boost::asio::post(m_ioCtx, [=, w = m_impl->weak_from_this()] {
233 if (auto impl = w.lock(); impl != nullptr) {
234 impl->setInterestFilter(id, filter, onInterest);
241 RegisteredPrefixHandle
242 Face::registerPrefix(
const Name& prefix,
251 auto id = m_impl->registerPrefix(prefix, onSuccess, onFailure, flags, options, std::nullopt,
nullptr);
258 if (m_ioCtx.stopped()) {
262 auto onThrow = make_scope_fail([
this] { m_impl->shutdown(); });
264 if (timeout < 0_ms) {
270 if (timeout > 0_ms) {
272 m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.schedule(timeout,
273 [&io = m_ioCtx, &work = m_impl->m_workGuard] {
281 m_impl->m_workGuard = make_unique<Impl::IoContextWorkGuard>(m_ioCtx.get_executor());
290 boost::asio::post(m_ioCtx, [
this, w = m_impl->weak_from_this()] {
291 if (auto impl = w.lock(); impl != nullptr) {
293 if (m_transport->getState() != Transport::State::CLOSED)
294 m_transport->close();
302 template<
typename NetPkt>
304 extractLpLocalFields(NetPkt& netPacket,
const lp::Packet& lpPacket)
306 addTagFromField<lp::IncomingFaceIdTag, lp::IncomingFaceIdField>(netPacket, lpPacket);
307 addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(netPacket, lpPacket);
311 Face::onReceiveElement(
const Block& blockFromDaemon)
313 lp::Packet lpPacket(blockFromDaemon);
317 Block netPacket({frag.first, frag.second});
318 switch (netPacket.type()) {
320 auto interest = make_shared<Interest>(netPacket);
322 auto nack = make_shared<lp::Nack>(std::move(*interest));
324 extractLpLocalFields(*nack, lpPacket);
325 NDN_LOG_DEBUG(
">N " << nack->getInterest() <<
'~' << nack->getHeader().getReason());
326 m_impl->nackPendingInterests(*nack);
329 extractLpLocalFields(*interest, lpPacket);
331 m_impl->processIncomingInterest(std::move(interest));
336 auto data = make_shared<Data>(netPacket);
337 extractLpLocalFields(*data, lpPacket);
339 m_impl->satisfyPendingInterests(*data);
345 PendingInterestHandle::PendingInterestHandle(weak_ptr<Face::Impl> weakImpl,
detail::RecordId id)
346 : CancelHandle([w = std::move(weakImpl), id] {
347 if (
auto impl = w.lock(); impl !=
nullptr) {
348 impl->asyncRemovePendingInterest(
id);
355 : CancelHandle([=] { unregister(weakImpl,
id,
nullptr,
nullptr); })
356 , m_weakImpl(std::move(weakImpl))
369 onFailure(
"RegisteredPrefixHandle is empty");
374 unregister(m_weakImpl, m_id, onSuccess, onFailure);
383 if (
auto impl = weakImpl.lock(); impl !=
nullptr) {
384 impl->asyncUnregisterPrefix(
id, onSuccess, onFailure);
386 else if (onFailure) {
387 onFailure(
"Face already closed");
392 : CancelHandle([w = std::move(weakImpl), id] {
393 if (
auto impl = w.lock(); impl !=
nullptr) {
394 impl->asyncUnsetInterestFilter(
id);
Represents a Data packet.
OversizedPacketError(char pktType, const Name &name, size_t wireSize)
Constructor.
Face(shared_ptr< Transport > transport=nullptr)
Create Face using the given Transport (or default transport if omitted).
Handle for a registered Interest filter.
InterestFilterHandle() noexcept=default
Declares the set of Interests a producer can serve.
const Name & getPrefix() const
Represents an Interest packet.
Represents an absolute name.
Handle for a pending Interest.
Handle for a registered prefix.
void unregister(const UnregisterPrefixSuccessCallback &onSuccess=nullptr, const UnregisterPrefixFailureCallback &onFailure=nullptr)
Unregister the prefix.
RegisteredPrefixHandle() noexcept=default
static shared_ptr< TcpTransport > create(const std::string &uri)
Create transport with parameters defined in URI.
static shared_ptr< UnixTransport > create(const std::string &uri)
Create transport with parameters defined in URI.
Represents a Network Nack.
Contains options for ControlCommand execution.
CommandOptions & setSigningInfo(security::SigningInfo signingInfo)
Sets the signing parameters.
The main interface for signing key management.
Signing parameters passed to KeyChain.
#define NDN_THROW_NESTED(e)
#define NDN_LOG_DEBUG(expression)
Log at DEBUG level.
std::string to_string(const errinfo_stacktrace &x)
FieldDecl< field_location_tags::Fragment, std::pair< Buffer::const_iterator, Buffer::const_iterator >, tlv::Fragment > FragmentField
Declare the Fragment field.
FieldDecl< field_location_tags::Header, NackHeader, tlv::Nack > NackField
::boost::chrono::milliseconds milliseconds
std::function< void(const Name &)> RegisterPrefixSuccessCallback
Callback invoked when registerPrefix or setInterestFilter command succeeds.
std::function< void(const Interest &)> TimeoutCallback
Callback invoked when an expressed Interest times out.
std::function< void(const std::string &)> UnregisterPrefixFailureCallback
Callback invoked when unregistering a prefix fails.
std::function< void(const Interest &, const lp::Nack &)> NackCallback
Callback invoked when a Nack is received in response to an expressed Interest.
std::function< void(const Interest &, const Data &)> DataCallback
Callback invoked when an expressed Interest is satisfied by a Data packet.
std::function< void()> UnregisterPrefixSuccessCallback
Callback invoked when unregistering a prefix succeeds.
std::function< void(const Name &, const std::string &)> RegisterPrefixFailureCallback
Callback invoked when registerPrefix or setInterestFilter command fails.
std::function< void(const InterestFilter &, const Interest &)> InterestCallback
Callback invoked when an incoming Interest matches the specified InterestFilter.
constexpr size_t MAX_NDN_PACKET_SIZE
Practical size limit of a network-layer packet.