22 #ifndef NDN_DETAIL_FACE_IMPL_HPP 23 #define NDN_DETAIL_FACE_IMPL_HPP 25 #include "../face.hpp" 30 #include "../lp/packet.hpp" 31 #include "../lp/tags.hpp" 32 #include "../mgmt/nfd/command-options.hpp" 33 #include "../mgmt/nfd/controller.hpp" 34 #include "../transport/tcp-transport.hpp" 35 #include "../transport/unix-transport.hpp" 36 #include "../util/config-file.hpp" 37 #include "../util/logger.hpp" 38 #include "../util/scheduler.hpp" 39 #include "../util/signal.hpp" 70 , m_processEventsTimeoutEvent(m_scheduler)
72 auto postOnEmptyPitOrNoRegisteredPrefixes = [
this] {
80 m_pendingInterestTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
81 m_registeredPrefixTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
94 const Interest& interest2 = *interest;
95 auto i = m_pendingInterestTable.insert(make_shared<PendingInterest>(
96 std::move(interest), afterSatisfied, afterNacked, afterTimeout, ref(m_scheduler))).first;
100 shared_ptr<PendingInterest> entry = *i;
101 entry->setDeleter([
this, i] { m_pendingInterestTable.erase(i); });
104 addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest2);
105 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest2);
107 entry->recordForwarding();
108 m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest2.wireEncode(),
109 'I', interest2.getName()));
116 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
122 m_pendingInterestTable.clear();
130 bool hasAppMatch =
false, hasForwarderMatch =
false;
131 for (
auto i = m_pendingInterestTable.begin(); i != m_pendingInterestTable.end(); ) {
132 shared_ptr<PendingInterest> entry = *i;
133 if (!entry->getInterest()->matchesData(data)) {
138 NDN_LOG_DEBUG(
" satisfying " << *entry->getInterest() <<
" from " << entry->getOrigin());
139 i = m_pendingInterestTable.erase(i);
143 entry->invokeDataCallback(data);
146 hasForwarderMatch =
true;
150 return hasForwarderMatch || !hasAppMatch;
158 optional<lp::Nack> outNack;
159 for (
auto i = m_pendingInterestTable.begin(); i != m_pendingInterestTable.end(); ) {
160 shared_ptr<PendingInterest> entry = *i;
166 NDN_LOG_DEBUG(
" nacking " << *entry->getInterest() <<
" from " << entry->getOrigin());
168 optional<lp::Nack> outNack1 = entry->recordNack(nack);
175 entry->invokeNackCallback(*outNack1);
180 i = m_pendingInterestTable.erase(i);
192 NDN_LOG_INFO(
"setting InterestFilter: " << interestFilterRecord->getFilter());
193 m_interestFilterTable.push_back(std::move(interestFilterRecord));
200 m_interestFilterTable.end(),
201 MatchInterestFilterId(interestFilterId));
202 if (i != m_interestFilterTable.end()) {
203 NDN_LOG_INFO(
"unsetting InterestFilter: " << (*i)->getFilter());
204 m_interestFilterTable.erase(i);
211 const Interest& interest2 = *interest;
212 auto i = m_pendingInterestTable.insert(make_shared<PendingInterest>(
213 std::move(interest), ref(m_scheduler))).first;
217 shared_ptr<PendingInterest> entry = *i;
218 entry->setDeleter([
this, i] { m_pendingInterestTable.erase(i); });
226 for (
const auto& filter : m_interestFilterTable) {
227 if (filter->doesMatch(entry)) {
229 entry.recordForwarding();
230 filter->invokeInterestCallback(interest);
240 if (!shouldSendToForwarder) {
247 addFieldFromTag<lp::CachePolicyField, lp::CachePolicyTag>(lpPacket, data);
248 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
250 m_face.m_transport->send(finishEncoding(std::move(lpPacket), data.wireEncode(),
251 'D', data.getName()));
267 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, *outNack);
269 const Interest& interest = outNack->getInterest();
270 m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest.wireEncode(),
271 'N', interest.getName()));
275 const RegisteredPrefixId*
277 shared_ptr<InterestFilterRecord> filter,
281 const nfd::CommandOptions& options)
284 auto record = make_shared<RegisteredPrefix>(prefix, filter, options);
289 m_face.m_nfdController->start<nfd::RibRegisterCommand>(
293 NDN_LOG_INFO(
"register prefix failed: " << record->getPrefix());
294 onFailure(record->getPrefix(), resp.getText());
298 return reinterpret_cast<const RegisteredPrefixId*
>(record.get());
305 NDN_LOG_INFO(
"registered prefix: " << registeredPrefix->getPrefix());
306 m_registeredPrefixTable.insert(registeredPrefix);
308 if (registeredPrefix->getFilter() !=
nullptr) {
310 m_interestFilterTable.push_back(registeredPrefix->getFilter());
313 if (onSuccess !=
nullptr) {
314 onSuccess(registeredPrefix->getPrefix());
323 auto i = std::find_if(m_registeredPrefixTable.begin(),
324 m_registeredPrefixTable.end(),
325 MatchRegisteredPrefixId(registeredPrefixId));
326 if (i != m_registeredPrefixTable.end()) {
327 RegisteredPrefix& record = **i;
328 const shared_ptr<InterestFilterRecord>& filter = record.getFilter();
330 if (filter !=
nullptr) {
332 m_interestFilterTable.remove(filter);
335 NDN_LOG_INFO(
"unregistering prefix: " << record.getPrefix());
338 params.
setName(record.getPrefix());
339 m_face.m_nfdController->start<nfd::RibUnregisterCommand>(
343 NDN_LOG_INFO(
"unregister prefix failed: " << params.getName());
344 onFailure(resp.getText());
346 record.getCommandOptions());
349 if (onFailure !=
nullptr) {
350 onFailure(
"Unrecognized PrefixId");
361 NDN_LOG_INFO(
"unregistered prefix: " << (*item)->getPrefix());
362 m_registeredPrefixTable.erase(item);
364 if (onSuccess !=
nullptr) {
373 if (!m_face.m_transport->isConnected())
374 m_face.m_transport->connect(m_face.getIoService(),
375 [=] (
const Block& wire) { m_face.onReceiveElement(wire); });
377 if (wantResume && !m_face.m_transport->isReceiving()) {
378 m_face.m_transport->resume();
385 if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
386 m_face.m_transport->pause();
402 if (!lpPacket.empty()) {
404 wire = lpPacket.wireEncode();
408 BOOST_THROW_EXCEPTION(Face::OversizedPacketError(pktType,
name, wire.size()));
416 util::Scheduler m_scheduler;
417 util::scheduler::ScopedEventId m_processEventsTimeoutEvent;
428 #endif // NDN_DETAIL_FACE_IMPL_HPP #define NDN_LOG_INFO(expression)
Copyright (c) 2011-2015 Regents of the University of California.
void ensureConnected(bool wantResume)
function< void(const std::string &)> UnregisterPrefixFailureCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command fails.
void asyncExpressInterest(shared_ptr< const Interest > interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
represents parameters in a ControlCommand request or response
implementation detail of Face
Packet & add(const typename FIELD::ValueType &value)
add a FIELD with value
bool matchesInterest(const Interest &other) const
Check if Interest matches other interest.
ControlParameters & setFlags(uint64_t flags)
void asyncUnsetInterestFilter(const InterestFilterId *interestFilterId)
const NackHeader & getHeader() const
void asyncSetInterestFilter(shared_ptr< InterestFilterRecord > interestFilterRecord)
void asyncUnregisterPrefix(const RegisteredPrefixId *registeredPrefixId, const UnregisterPrefixSuccessCallback &onSuccess, const UnregisterPrefixFailureCallback &onFailure)
void asyncPutNack(const lp::Nack &nack)
represents a Network Nack
void asyncPutData(const Data &data)
Table::const_iterator iterator
#define NDN_LOG_INIT(name)
declare a log module
#define NDN_LOG_DEBUG(expression)
void finalizeUnregisterPrefix(RegisteredPrefixTable::iterator item, const UnregisterPrefixSuccessCallback &onSuccess)
Provide a communication channel with local or remote NDN forwarder.
void asyncRemoveAllPendingInterests()
const RegisteredPrefixId * registerPrefix(const Name &prefix, shared_ptr< InterestFilterRecord > filter, const RegisterPrefixSuccessCallback &onSuccess, const RegisterPrefixFailureCallback &onFailure, uint64_t flags, const nfd::CommandOptions &options)
function< void(const Name &, const std::string &)> RegisterPrefixFailureCallback
Callback invoked when registerPrefix or setInterestFilter command fails.
void processIncomingInterest(shared_ptr< const Interest > interest)
function< void(const Name &)> RegisterPrefixSuccessCallback
Callback invoked when registerPrefix or setInterestFilter command succeeds.
bool satisfyPendingInterests(const Data &data)
boost::asio::io_service & getIoService()
Return nullptr (cannot use IoService in simulations), preserved for API compatibility.
std::list< shared_ptr< InterestFilterRecord > > InterestFilterTable
ControlParameters & setName(const Name &name)
function< void()> UnregisterPrefixSuccessCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds.
void asyncRemovePendingInterest(const PendingInterestId *pendingInterestId)
Interest was received from this app via Face::expressInterest API.
ContainerWithOnEmptySignal< shared_ptr< PendingInterest > > PendingInterestTable
function< void(const Interest &)> TimeoutCallback
Callback invoked when expressed Interest times out.
function< void(const Interest &, const lp::Nack &)> NackCallback
Callback invoked when Nack is sent in response to expressed Interest.
ContainerWithOnEmptySignal< shared_ptr< RegisteredPrefix > > RegisteredPrefixTable
const Interest & getInterest() const
function< void(const Interest &, const Data &)> DataCallback
Callback invoked when expressed Interest gets satisfied with a Data packet.
void dispatchInterest(PendingInterest &entry, const Interest &interest)
void onEmptyPitOrNoRegisteredPrefixes()
const size_t MAX_NDN_PACKET_SIZE
practical limit of network layer packet size
optional< lp::Nack > nackPendingInterests(const lp::Nack &nack)
void afterPrefixRegistered(shared_ptr< RegisteredPrefix > registeredPrefix, const RegisterPrefixSuccessCallback &onSuccess)