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);
93 const Interest& interest2 = *interest;
94 auto i = m_pendingInterestTable.insert(make_shared<PendingInterest>(
95 std::move(interest), afterSatisfied, afterNacked, afterTimeout, ref(m_scheduler))).first;
96 PendingInterest& entry = **i;
97 entry.setDeleter([
this, i] { m_pendingInterestTable.erase(i); });
100 addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest2);
101 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest2);
103 entry.recordForwarding();
104 m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest2.wireEncode(),
105 'I', interest2.getName()));
111 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
117 m_pendingInterestTable.clear();
125 bool hasAppMatch =
false, hasForwarderMatch =
false;
126 for (
auto i = m_pendingInterestTable.begin(); i != m_pendingInterestTable.end(); ) {
127 shared_ptr<PendingInterest> entry = *i;
128 if (!entry->getInterest()->matchesData(data)) {
133 NDN_LOG_DEBUG(
" satisfying " << *entry->getInterest() <<
" from " << entry->getOrigin());
134 i = m_pendingInterestTable.erase(i);
138 entry->invokeDataCallback(data);
141 hasForwarderMatch =
true;
145 return hasForwarderMatch || !hasAppMatch;
153 optional<lp::Nack> outNack;
154 for (
auto i = m_pendingInterestTable.begin(); i != m_pendingInterestTable.end(); ) {
155 shared_ptr<PendingInterest> entry = *i;
161 NDN_LOG_DEBUG(
" nacking " << *entry->getInterest() <<
" from " << entry->getOrigin());
163 optional<lp::Nack> outNack1 = entry->recordNack(nack);
170 entry->invokeNackCallback(*outNack1);
175 i = m_pendingInterestTable.erase(i);
187 NDN_LOG_INFO(
"setting InterestFilter: " << interestFilterRecord->getFilter());
188 m_interestFilterTable.push_back(std::move(interestFilterRecord));
195 m_interestFilterTable.end(),
196 MatchInterestFilterId(interestFilterId));
197 if (i != m_interestFilterTable.end()) {
198 NDN_LOG_INFO(
"unsetting InterestFilter: " << (*i)->getFilter());
199 m_interestFilterTable.erase(i);
206 const Interest& interest2 = *interest;
207 auto i = m_pendingInterestTable.insert(make_shared<PendingInterest>(
208 std::move(interest), ref(m_scheduler))).first;
211 shared_ptr<PendingInterest> entry = *i;
212 entry->setDeleter([
this, i] { m_pendingInterestTable.erase(i); });
214 for (
const auto& filter : m_interestFilterTable) {
215 if (filter->doesMatch(interest2.getName())) {
217 entry->recordForwarding();
218 filter->invokeInterestCallback(interest2);
227 if (!shouldSendToForwarder) {
234 addFieldFromTag<lp::CachePolicyField, lp::CachePolicyTag>(lpPacket, data);
235 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
237 m_face.m_transport->send(finishEncoding(std::move(lpPacket), data.wireEncode(),
238 'D', data.getName()));
253 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, *outNack);
255 const Interest& interest = outNack->getInterest();
256 m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest.wireEncode(),
257 'N', interest.getName()));
261 const RegisteredPrefixId*
263 shared_ptr<InterestFilterRecord> filter,
267 const nfd::CommandOptions& options)
270 auto record = make_shared<RegisteredPrefix>(prefix, filter, options);
275 m_face.m_nfdController->start<nfd::RibRegisterCommand>(
279 NDN_LOG_INFO(
"register prefix failed: " << record->getPrefix());
280 onFailure(record->getPrefix(), resp.getText());
284 return reinterpret_cast<const RegisteredPrefixId*
>(record.get());
291 NDN_LOG_INFO(
"registered prefix: " << registeredPrefix->getPrefix());
292 m_registeredPrefixTable.insert(registeredPrefix);
294 if (registeredPrefix->getFilter() !=
nullptr) {
296 m_interestFilterTable.push_back(registeredPrefix->getFilter());
299 if (onSuccess !=
nullptr) {
300 onSuccess(registeredPrefix->getPrefix());
309 auto i = std::find_if(m_registeredPrefixTable.begin(),
310 m_registeredPrefixTable.end(),
311 MatchRegisteredPrefixId(registeredPrefixId));
312 if (i != m_registeredPrefixTable.end()) {
313 RegisteredPrefix& record = **i;
314 const shared_ptr<InterestFilterRecord>& filter = record.getFilter();
316 if (filter !=
nullptr) {
318 m_interestFilterTable.remove(filter);
321 NDN_LOG_INFO(
"unregistering prefix: " << record.getPrefix());
324 params.
setName(record.getPrefix());
325 m_face.m_nfdController->start<nfd::RibUnregisterCommand>(
329 NDN_LOG_INFO(
"unregister prefix failed: " << params.getName());
330 onFailure(resp.getText());
332 record.getCommandOptions());
335 if (onFailure !=
nullptr) {
336 onFailure(
"Unrecognized PrefixId");
347 NDN_LOG_INFO(
"unregistered prefix: " << (*item)->getPrefix());
348 m_registeredPrefixTable.erase(item);
350 if (onSuccess !=
nullptr) {
359 if (!m_face.m_transport->isConnected())
360 m_face.m_transport->connect(m_face.getIoService(),
361 [=] (
const Block& wire) { m_face.onReceiveElement(wire); });
363 if (wantResume && !m_face.m_transport->isReceiving()) {
364 m_face.m_transport->resume();
371 if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
372 m_face.m_transport->pause();
388 if (!lpPacket.empty()) {
390 wire = lpPacket.wireEncode();
394 BOOST_THROW_EXCEPTION(Face::OversizedPacketError(pktType, name, wire.size()));
402 util::Scheduler m_scheduler;
403 util::scheduler::ScopedEventId m_processEventsTimeoutEvent;
414 #endif // NDN_DETAIL_FACE_IMPL_HPP #define NDN_LOG_INFO(expression)
Copyright (c) 2011-2015 Regents of the University of California.
ContainerWithOnEmptySignal< shared_ptr< RegisteredPrefix >> RegisteredPrefixTable
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
std::list< shared_ptr< InterestFilterRecord >> InterestFilterTable
Packet & add(const typename FIELD::ValueType &value)
add a FIELD with value
const Interest & getInterest() const
ControlParameters & setFlags(uint64_t flags)
void asyncUnsetInterestFilter(const InterestFilterId *interestFilterId)
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
ContainerWithOnEmptySignal< shared_ptr< PendingInterest >> PendingInterestTable
#define NDN_LOG_DEBUG(expression)
mgmt::ControlResponse ControlResponse
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.
bool matchesInterest(const Interest &other) const
Check if Interest matches other interest.
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.
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.
function< void(const Interest &, const Data &)> DataCallback
Callback invoked when expressed Interest gets satisfied with a Data packet.
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)