blob: 1d53eab857008f50c2a50ad6bffd35f24ab9e6db [file] [log] [blame]
Yanbiao Li73860e32015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry944f38b2017-07-20 20:54:22 -04002/*
Davide Pesavento15b55052018-01-27 19:09:28 -05003 * Copyright (c) 2014-2018, Regents of the University of California,
Yanbiao Li73860e32015-08-19 16:30:16 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "face-manager.hpp"
Davide Pesaventoa3148082018-04-12 18:21:54 -040027
28#include "core/logger.hpp"
Junxiao Shi40cb61c2015-09-23 18:36:45 -070029#include "face/generic-link-service.hpp"
Junxiao Shib8590312016-12-29 21:22:25 +000030#include "face/protocol-factory.hpp"
Yukai Tu0a49d342015-09-13 12:54:22 +080031#include "fw/face-table.hpp"
Yanbiao Li73860e32015-08-19 16:30:16 -070032
Eric Newberry0c3e57b2018-01-25 20:54:46 -070033#include <boost/logic/tribool.hpp>
34
Junxiao Shicbc8e942016-09-06 03:17:45 +000035#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000036#include <ndn-cxx/mgmt/nfd/channel-status.hpp>
Yanbiao Li73860e32015-08-19 16:30:16 -070037
Yanbiao Li73860e32015-08-19 16:30:16 -070038namespace nfd {
39
Davide Pesaventoa3148082018-04-12 18:21:54 -040040NFD_LOG_INIT(FaceManager);
Yanbiao Li73860e32015-08-19 16:30:16 -070041
Junxiao Shiea47bde2017-01-26 17:49:16 +000042FaceManager::FaceManager(FaceSystem& faceSystem,
Davide Pesaventocfb1a312018-03-01 01:30:56 -050043 Dispatcher& dispatcher,
44 CommandAuthenticator& authenticator)
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000045 : NfdManagerBase(dispatcher, authenticator, "faces")
Junxiao Shiea47bde2017-01-26 17:49:16 +000046 , m_faceSystem(faceSystem)
47 , m_faceTable(faceSystem.getFaceTable())
Yanbiao Li73860e32015-08-19 16:30:16 -070048{
Yanbiao Li58ba3f92017-02-15 14:27:18 +000049 // register handlers for ControlCommand
Yanbiao Li73860e32015-08-19 16:30:16 -070050 registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
51 bind(&FaceManager::createFace, this, _2, _3, _4, _5));
52
Eric Newberryb5aa7f52016-09-03 20:36:12 -070053 registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
54 bind(&FaceManager::updateFace, this, _2, _3, _4, _5));
55
Yanbiao Li73860e32015-08-19 16:30:16 -070056 registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
57 bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
58
Yanbiao Li58ba3f92017-02-15 14:27:18 +000059 // register handlers for StatusDataset
Yanbiao Li73860e32015-08-19 16:30:16 -070060 registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
61 registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
62 registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
63
Yanbiao Li58ba3f92017-02-15 14:27:18 +000064 // register notification stream
Junxiao Shiae04d342016-07-19 13:20:22 +000065 m_postNotification = registerNotificationStream("events");
Eric Newberry1b4ba052016-10-07 23:04:07 -070066 m_faceAddConn = m_faceTable.afterAdd.connect([this] (const Face& face) {
67 connectFaceStateChangeSignal(face);
68 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
69 });
70 m_faceRemoveConn = m_faceTable.beforeRemove.connect([this] (const Face& face) {
71 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
72 });
Yanbiao Li73860e32015-08-19 16:30:16 -070073}
74
75void
Yanbiao Li73860e32015-08-19 16:30:16 -070076FaceManager::createFace(const Name& topPrefix, const Interest& interest,
77 const ControlParameters& parameters,
78 const ndn::mgmt::CommandContinuation& done)
79{
Eric Newberry78e32b02017-04-01 14:34:44 +000080 FaceUri remoteUri;
81 if (!remoteUri.parse(parameters.getUri())) {
82 NFD_LOG_TRACE("failed to parse remote URI: " << parameters.getUri());
Eric Newberry42602412016-08-27 09:33:18 -070083 done(ControlResponse(400, "Malformed command"));
84 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070085 }
86
Eric Newberry78e32b02017-04-01 14:34:44 +000087 if (!remoteUri.isCanonical()) {
88 NFD_LOG_TRACE("received non-canonical remote URI: " << remoteUri.toString());
89 done(ControlResponse(400, "Non-canonical remote URI"));
Eric Newberry42602412016-08-27 09:33:18 -070090 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070091 }
92
Davide Pesavento87fc0f82018-04-11 23:43:51 -040093 optional<FaceUri> localUri;
Eric Newberry78e32b02017-04-01 14:34:44 +000094 if (parameters.hasLocalUri()) {
95 localUri = FaceUri{};
96
97 if (!localUri->parse(parameters.getLocalUri())) {
98 NFD_LOG_TRACE("failed to parse local URI: " << parameters.getLocalUri());
99 done(ControlResponse(400, "Malformed command"));
100 return;
101 }
102
103 if (!localUri->isCanonical()) {
104 NFD_LOG_TRACE("received non-canonical local URI: " << localUri->toString());
105 done(ControlResponse(400, "Non-canonical local URI"));
106 return;
107 }
108 }
109
Davide Pesaventoe5eebad2017-04-06 20:23:26 -0400110 face::ProtocolFactory* factory = m_faceSystem.getFactoryByScheme(remoteUri.getScheme());
Junxiao Shib8590312016-12-29 21:22:25 +0000111 if (factory == nullptr) {
Eric Newberry78e32b02017-04-01 14:34:44 +0000112 NFD_LOG_TRACE("received create request for unsupported protocol: " << remoteUri.getScheme());
Eric Newberry42602412016-08-27 09:33:18 -0700113 done(ControlResponse(406, "Unsupported protocol"));
114 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700115 }
116
Davide Pesavento15b55052018-01-27 19:09:28 -0500117 face::FaceParams faceParams;
118 faceParams.persistency = parameters.getFacePersistency();
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700119 if (parameters.hasBaseCongestionMarkingInterval()) {
120 faceParams.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
121 }
122 if (parameters.hasDefaultCongestionThreshold()) {
123 faceParams.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
124 }
Davide Pesavento15b55052018-01-27 19:09:28 -0500125 faceParams.wantLocalFields = parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
126 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
127 faceParams.wantLpReliability = parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) &&
128 parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700129 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
130 faceParams.wantCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
131 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700132 try {
Davide Pesavento15b55052018-01-27 19:09:28 -0500133 factory->createFace({remoteUri, localUri, faceParams},
134 bind(&FaceManager::afterCreateFaceSuccess, this, parameters, _1, done),
135 bind(&FaceManager::afterCreateFaceFailure, this, _1, _2, done));
Yanbiao Li73860e32015-08-19 16:30:16 -0700136 }
137 catch (const std::runtime_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700138 NFD_LOG_ERROR("Face creation failed: " << error.what());
139 done(ControlResponse(500, "Face creation failed due to internal error"));
140 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700141 }
142 catch (const std::logic_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700143 NFD_LOG_ERROR("Face creation failed: " << error.what());
144 done(ControlResponse(500, "Face creation failed due to internal error"));
145 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700146 }
147}
148
149void
Eric Newberry42602412016-08-27 09:33:18 -0700150FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
Eric Newberryf40551a2016-09-05 15:41:16 -0700151 const shared_ptr<Face>& face,
Yanbiao Li73860e32015-08-19 16:30:16 -0700152 const ndn::mgmt::CommandContinuation& done)
153{
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000154 if (face->getId() != face::INVALID_FACEID) {// Face already exists
155 NFD_LOG_TRACE("Attempted to create duplicate face of " << face->getId());
156
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000157 ControlParameters response = collectFaceProperties(*face, true);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000158 done(ControlResponse(409, "Face with remote URI already exists").setBody(response.wireEncode()));
159 return;
160 }
161
Eric Newberryf40551a2016-09-05 15:41:16 -0700162 // If scope non-local and flags set to enable local fields, request shouldn't
163 // have made it this far
164 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
165 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
166 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
167 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
168
169 m_faceTable.add(face);
170
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000171 ControlParameters response = collectFaceProperties(*face, true);
Eric Newberry42602412016-08-27 09:33:18 -0700172 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
173}
174
175void
176FaceManager::afterCreateFaceFailure(uint32_t status,
177 const std::string& reason,
178 const ndn::mgmt::CommandContinuation& done)
179{
180 NFD_LOG_DEBUG("Face creation failed: " << reason);
181
182 done(ControlResponse(status, reason));
Yanbiao Li73860e32015-08-19 16:30:16 -0700183}
184
185void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700186FaceManager::updateFace(const Name& topPrefix, const Interest& interest,
187 const ControlParameters& parameters,
188 const ndn::mgmt::CommandContinuation& done)
189{
190 FaceId faceId = parameters.getFaceId();
191 if (faceId == 0) {
192 // Self-updating
193 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
194 if (incomingFaceIdTag == nullptr) {
195 NFD_LOG_TRACE("unable to determine face for self-update");
196 done(ControlResponse(404, "No FaceId specified and IncomingFaceId not available"));
197 return;
198 }
199 faceId = *incomingFaceIdTag;
200 }
201
202 Face* face = m_faceTable.get(faceId);
203
204 if (face == nullptr) {
205 NFD_LOG_TRACE("invalid face specified");
206 done(ControlResponse(404, "Specified face does not exist"));
207 return;
208 }
209
210 // Verify validity of requested changes
211 ControlParameters response;
212 bool areParamsValid = true;
213
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700214 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
215 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
216 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
217 NFD_LOG_TRACE("received request to enable local fields on non-local face");
218 areParamsValid = false;
219 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
220 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
221 }
222
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000223 // check whether the requested FacePersistency change is valid if it's present
224 if (parameters.hasFacePersistency()) {
225 auto persistency = parameters.getFacePersistency();
226 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
227 NFD_LOG_TRACE("cannot change face persistency to " << persistency);
228 areParamsValid = false;
229 response.setFacePersistency(persistency);
230 }
231 }
232
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700233 if (!areParamsValid) {
234 done(ControlResponse(409, "Invalid properties specified").setBody(response.wireEncode()));
235 return;
236 }
237
238 // All specified properties are valid, so make changes
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000239 if (parameters.hasFacePersistency()) {
240 face->setPersistency(parameters.getFacePersistency());
241 }
Eric Newberry2642cd22017-07-13 21:34:53 -0400242 setLinkServiceOptions(*face, parameters);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700243
Eric Newberryf40551a2016-09-05 15:41:16 -0700244 // Set ControlResponse fields
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000245 response = collectFaceProperties(*face, false);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700246
247 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
248}
249
250void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700251FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
252 const ControlParameters& parameters,
253 const ndn::mgmt::CommandContinuation& done)
254{
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000255 Face* face = m_faceTable.get(parameters.getFaceId());
256 if (face != nullptr) {
257 face->close();
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700258 }
259
260 done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
261}
262
263void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700264FaceManager::setLinkServiceOptions(Face& face,
Eric Newberry2642cd22017-07-13 21:34:53 -0400265 const ControlParameters& parameters)
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700266{
267 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
268 BOOST_ASSERT(linkService != nullptr);
269
270 auto options = linkService->getOptions();
271 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
272 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
273 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
274 }
Eric Newberry2642cd22017-07-13 21:34:53 -0400275 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
276 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
277 }
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700278 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
279 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
280 }
281 if (parameters.hasBaseCongestionMarkingInterval()) {
282 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
283 }
284 if (parameters.hasDefaultCongestionThreshold()) {
285 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
286 }
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700287 linkService->setOptions(options);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700288}
289
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000290ControlParameters
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000291FaceManager::collectFaceProperties(const Face& face, bool wantUris)
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000292{
293 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
294 BOOST_ASSERT(linkService != nullptr);
295 auto options = linkService->getOptions();
296
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000297 ControlParameters params;
298 params.setFaceId(face.getId())
299 .setFacePersistency(face.getPersistency())
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700300 .setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
301 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
Eric Newberry2642cd22017-07-13 21:34:53 -0400302 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false)
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700303 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled, false)
304 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking, false);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000305 if (wantUris) {
306 params.setUri(face.getRemoteUri().toString())
307 .setLocalUri(face.getLocalUri().toString());
308 }
309 return params;
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000310}
311
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700312void
Yanbiao Li73860e32015-08-19 16:30:16 -0700313FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
314 ndn::mgmt::StatusDatasetContext& context)
315{
Eric Newberryc64d30a2015-12-26 11:07:27 -0700316 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000317 for (const Face& face : m_faceTable) {
318 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700319 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700320 }
321 context.end();
322}
323
324void
325FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
326 ndn::mgmt::StatusDatasetContext& context)
327{
Davide Pesaventoe5eebad2017-04-06 20:23:26 -0400328 std::set<const face::ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
329 for (const auto* factory : factories) {
Junxiao Shib8590312016-12-29 21:22:25 +0000330 for (const auto& channel : factory->getChannels()) {
331 ndn::nfd::ChannelStatus entry;
332 entry.setLocalUri(channel->getUri().toString());
333 context.append(entry.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700334 }
335 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700336 context.end();
337}
338
339void
340FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
341 ndn::mgmt::StatusDatasetContext& context)
342{
343 ndn::nfd::FaceQueryFilter faceFilter;
344 const Name& query = interest.getName();
345 try {
346 faceFilter.wireDecode(query[-1].blockFromValue());
347 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200348 catch (const tlv::Error& e) {
349 NFD_LOG_DEBUG("Malformed query filter: " << e.what());
350 return context.reject(ControlResponse(400, "Malformed filter"));
Yanbiao Li73860e32015-08-19 16:30:16 -0700351 }
352
Eric Newberryc64d30a2015-12-26 11:07:27 -0700353 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000354 for (const Face& face : m_faceTable) {
355 if (!matchFilter(faceFilter, face)) {
Junxiao Shida93f1f2015-11-11 06:13:16 -0700356 continue;
Yanbiao Li73860e32015-08-19 16:30:16 -0700357 }
Junxiao Shib84e6742016-07-19 13:16:22 +0000358 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700359 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700360 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200361
Yanbiao Li73860e32015-08-19 16:30:16 -0700362 context.end();
363}
364
365bool
Junxiao Shib84e6742016-07-19 13:16:22 +0000366FaceManager::matchFilter(const ndn::nfd::FaceQueryFilter& filter, const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700367{
368 if (filter.hasFaceId() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000369 filter.getFaceId() != static_cast<uint64_t>(face.getId())) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700370 return false;
371 }
372
373 if (filter.hasUriScheme() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000374 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
375 filter.getUriScheme() != face.getLocalUri().getScheme()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700376 return false;
377 }
378
379 if (filter.hasRemoteUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000380 filter.getRemoteUri() != face.getRemoteUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700381 return false;
382 }
383
384 if (filter.hasLocalUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000385 filter.getLocalUri() != face.getLocalUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700386 return false;
387 }
388
389 if (filter.hasFaceScope() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000390 filter.getFaceScope() != face.getScope()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700391 return false;
392 }
393
394 if (filter.hasFacePersistency() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000395 filter.getFacePersistency() != face.getPersistency()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700396 return false;
397 }
398
399 if (filter.hasLinkType() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000400 filter.getLinkType() != face.getLinkType()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700401 return false;
402 }
403
404 return true;
405}
406
Eric Newberryc64d30a2015-12-26 11:07:27 -0700407ndn::nfd::FaceStatus
408FaceManager::collectFaceStatus(const Face& face, const time::steady_clock::TimePoint& now)
409{
410 ndn::nfd::FaceStatus status;
411
412 collectFaceProperties(face, status);
413
414 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
415 if (expirationTime != time::steady_clock::TimePoint::max()) {
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700416 status.setExpirationPeriod(std::max(0_ms,
Eric Newberryc64d30a2015-12-26 11:07:27 -0700417 time::duration_cast<time::milliseconds>(expirationTime - now)));
418 }
419
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700420 // Get LinkService options
421 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
422 if (linkService != nullptr) {
423 auto linkServiceOptions = linkService->getOptions();
424 status.setBaseCongestionMarkingInterval(linkServiceOptions.baseCongestionMarkingInterval);
425 status.setDefaultCongestionThreshold(linkServiceOptions.defaultCongestionThreshold);
426 }
427
Eric Newberryc64d30a2015-12-26 11:07:27 -0700428 const face::FaceCounters& counters = face.getCounters();
429 status.setNInInterests(counters.nInInterests)
430 .setNOutInterests(counters.nOutInterests)
Junxiao Shif03d4792017-04-06 16:41:22 +0000431 .setNInData(counters.nInData)
432 .setNOutData(counters.nOutData)
Eric Newberryc64d30a2015-12-26 11:07:27 -0700433 .setNInNacks(counters.nInNacks)
434 .setNOutNacks(counters.nOutNacks)
435 .setNInBytes(counters.nInBytes)
436 .setNOutBytes(counters.nOutBytes);
437
438 return status;
439}
440
Junxiao Shida93f1f2015-11-11 06:13:16 -0700441template<typename FaceTraits>
Junxiao Shicde37ad2015-12-24 01:02:05 -0700442void
443FaceManager::collectFaceProperties(const Face& face, FaceTraits& traits)
Junxiao Shida93f1f2015-11-11 06:13:16 -0700444{
445 traits.setFaceId(face.getId())
446 .setRemoteUri(face.getRemoteUri().toString())
447 .setLocalUri(face.getLocalUri().toString())
448 .setFaceScope(face.getScope())
449 .setFacePersistency(face.getPersistency())
450 .setLinkType(face.getLinkType());
Eric Newberry1b4ba052016-10-07 23:04:07 -0700451
452 // Set Flag bits
453 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
454 if (linkService != nullptr) {
455 auto linkServiceOptions = linkService->getOptions();
456 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400457 traits.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED,
458 linkServiceOptions.reliabilityOptions.isEnabled);
Eric Newberryde332452018-01-30 11:45:32 -0700459 traits.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED,
460 linkServiceOptions.allowCongestionMarking);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700461 }
Junxiao Shida93f1f2015-11-11 06:13:16 -0700462}
463
464void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700465FaceManager::notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind)
Yanbiao Li73860e32015-08-19 16:30:16 -0700466{
467 ndn::nfd::FaceEventNotification notification;
Eric Newberry1b4ba052016-10-07 23:04:07 -0700468 notification.setKind(kind);
Junxiao Shiae04d342016-07-19 13:20:22 +0000469 collectFaceProperties(face, notification);
Yanbiao Li73860e32015-08-19 16:30:16 -0700470
Junxiao Shiae04d342016-07-19 13:20:22 +0000471 m_postNotification(notification.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700472}
473
474void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700475FaceManager::connectFaceStateChangeSignal(const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700476{
Davide Pesavento3cf75dc2018-03-17 00:38:03 -0400477 using face::FaceState;
478
Eric Newberry1b4ba052016-10-07 23:04:07 -0700479 FaceId faceId = face.getId();
480 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
Davide Pesavento3cf75dc2018-03-17 00:38:03 -0400481 [this, faceId, &face] (FaceState oldState, FaceState newState) {
482 if (newState == FaceState::UP) {
Eric Newberry1b4ba052016-10-07 23:04:07 -0700483 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
484 }
Davide Pesavento3cf75dc2018-03-17 00:38:03 -0400485 else if (newState == FaceState::DOWN) {
Eric Newberry1b4ba052016-10-07 23:04:07 -0700486 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
487 }
Davide Pesavento3cf75dc2018-03-17 00:38:03 -0400488 else if (newState == FaceState::CLOSED) {
489 // cannot use face.getId() because it may already be reset to INVALID_FACEID
Eric Newberry1b4ba052016-10-07 23:04:07 -0700490 m_faceStateChangeConn.erase(faceId);
491 }
492 });
Yanbiao Li73860e32015-08-19 16:30:16 -0700493}
494
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200495} // namespace nfd