blob: ba7cb365bd0deb74b3b8d82870da13eff18c52b8 [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"
Junxiao Shi40cb61c2015-09-23 18:36:45 -070027#include "face/generic-link-service.hpp"
Junxiao Shib8590312016-12-29 21:22:25 +000028#include "face/protocol-factory.hpp"
Yukai Tu0a49d342015-09-13 12:54:22 +080029#include "fw/face-table.hpp"
Yanbiao Li73860e32015-08-19 16:30:16 -070030
Eric Newberry0c3e57b2018-01-25 20:54:46 -070031#include <boost/logic/tribool.hpp>
32
Junxiao Shicbc8e942016-09-06 03:17:45 +000033#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000034#include <ndn-cxx/mgmt/nfd/channel-status.hpp>
Yanbiao Li73860e32015-08-19 16:30:16 -070035
Yanbiao Li73860e32015-08-19 16:30:16 -070036namespace nfd {
37
38NFD_LOG_INIT("FaceManager");
39
Junxiao Shiea47bde2017-01-26 17:49:16 +000040FaceManager::FaceManager(FaceSystem& faceSystem,
Davide Pesaventocfb1a312018-03-01 01:30:56 -050041 Dispatcher& dispatcher,
42 CommandAuthenticator& authenticator)
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000043 : NfdManagerBase(dispatcher, authenticator, "faces")
Junxiao Shiea47bde2017-01-26 17:49:16 +000044 , m_faceSystem(faceSystem)
45 , m_faceTable(faceSystem.getFaceTable())
Yanbiao Li73860e32015-08-19 16:30:16 -070046{
Yanbiao Li58ba3f92017-02-15 14:27:18 +000047 // register handlers for ControlCommand
Yanbiao Li73860e32015-08-19 16:30:16 -070048 registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
49 bind(&FaceManager::createFace, this, _2, _3, _4, _5));
50
Eric Newberryb5aa7f52016-09-03 20:36:12 -070051 registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
52 bind(&FaceManager::updateFace, this, _2, _3, _4, _5));
53
Yanbiao Li73860e32015-08-19 16:30:16 -070054 registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
55 bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
56
Yanbiao Li58ba3f92017-02-15 14:27:18 +000057 // register handlers for StatusDataset
Yanbiao Li73860e32015-08-19 16:30:16 -070058 registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
59 registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
60 registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
61
Yanbiao Li58ba3f92017-02-15 14:27:18 +000062 // register notification stream
Junxiao Shiae04d342016-07-19 13:20:22 +000063 m_postNotification = registerNotificationStream("events");
Eric Newberry1b4ba052016-10-07 23:04:07 -070064 m_faceAddConn = m_faceTable.afterAdd.connect([this] (const Face& face) {
65 connectFaceStateChangeSignal(face);
66 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
67 });
68 m_faceRemoveConn = m_faceTable.beforeRemove.connect([this] (const Face& face) {
69 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
70 });
Yanbiao Li73860e32015-08-19 16:30:16 -070071}
72
73void
Yanbiao Li73860e32015-08-19 16:30:16 -070074FaceManager::createFace(const Name& topPrefix, const Interest& interest,
75 const ControlParameters& parameters,
76 const ndn::mgmt::CommandContinuation& done)
77{
Eric Newberry78e32b02017-04-01 14:34:44 +000078 FaceUri remoteUri;
79 if (!remoteUri.parse(parameters.getUri())) {
80 NFD_LOG_TRACE("failed to parse remote URI: " << parameters.getUri());
Eric Newberry42602412016-08-27 09:33:18 -070081 done(ControlResponse(400, "Malformed command"));
82 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070083 }
84
Eric Newberry78e32b02017-04-01 14:34:44 +000085 if (!remoteUri.isCanonical()) {
86 NFD_LOG_TRACE("received non-canonical remote URI: " << remoteUri.toString());
87 done(ControlResponse(400, "Non-canonical remote URI"));
Eric Newberry42602412016-08-27 09:33:18 -070088 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070089 }
90
Eric Newberry78e32b02017-04-01 14:34:44 +000091 ndn::optional<FaceUri> localUri;
92 if (parameters.hasLocalUri()) {
93 localUri = FaceUri{};
94
95 if (!localUri->parse(parameters.getLocalUri())) {
96 NFD_LOG_TRACE("failed to parse local URI: " << parameters.getLocalUri());
97 done(ControlResponse(400, "Malformed command"));
98 return;
99 }
100
101 if (!localUri->isCanonical()) {
102 NFD_LOG_TRACE("received non-canonical local URI: " << localUri->toString());
103 done(ControlResponse(400, "Non-canonical local URI"));
104 return;
105 }
106 }
107
Davide Pesaventoe5eebad2017-04-06 20:23:26 -0400108 face::ProtocolFactory* factory = m_faceSystem.getFactoryByScheme(remoteUri.getScheme());
Junxiao Shib8590312016-12-29 21:22:25 +0000109 if (factory == nullptr) {
Eric Newberry78e32b02017-04-01 14:34:44 +0000110 NFD_LOG_TRACE("received create request for unsupported protocol: " << remoteUri.getScheme());
Eric Newberry42602412016-08-27 09:33:18 -0700111 done(ControlResponse(406, "Unsupported protocol"));
112 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700113 }
114
Davide Pesavento15b55052018-01-27 19:09:28 -0500115 face::FaceParams faceParams;
116 faceParams.persistency = parameters.getFacePersistency();
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700117 if (parameters.hasBaseCongestionMarkingInterval()) {
118 faceParams.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
119 }
120 if (parameters.hasDefaultCongestionThreshold()) {
121 faceParams.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
122 }
Davide Pesavento15b55052018-01-27 19:09:28 -0500123 faceParams.wantLocalFields = parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
124 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
125 faceParams.wantLpReliability = parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) &&
126 parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700127 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
128 faceParams.wantCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
129 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700130 try {
Davide Pesavento15b55052018-01-27 19:09:28 -0500131 factory->createFace({remoteUri, localUri, faceParams},
132 bind(&FaceManager::afterCreateFaceSuccess, this, parameters, _1, done),
133 bind(&FaceManager::afterCreateFaceFailure, this, _1, _2, done));
Yanbiao Li73860e32015-08-19 16:30:16 -0700134 }
135 catch (const std::runtime_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700136 NFD_LOG_ERROR("Face creation failed: " << error.what());
137 done(ControlResponse(500, "Face creation failed due to internal error"));
138 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700139 }
140 catch (const std::logic_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700141 NFD_LOG_ERROR("Face creation failed: " << error.what());
142 done(ControlResponse(500, "Face creation failed due to internal error"));
143 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700144 }
145}
146
147void
Eric Newberry42602412016-08-27 09:33:18 -0700148FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
Eric Newberryf40551a2016-09-05 15:41:16 -0700149 const shared_ptr<Face>& face,
Yanbiao Li73860e32015-08-19 16:30:16 -0700150 const ndn::mgmt::CommandContinuation& done)
151{
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000152 if (face->getId() != face::INVALID_FACEID) {// Face already exists
153 NFD_LOG_TRACE("Attempted to create duplicate face of " << face->getId());
154
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000155 ControlParameters response = collectFaceProperties(*face, true);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000156 done(ControlResponse(409, "Face with remote URI already exists").setBody(response.wireEncode()));
157 return;
158 }
159
Eric Newberryf40551a2016-09-05 15:41:16 -0700160 // If scope non-local and flags set to enable local fields, request shouldn't
161 // have made it this far
162 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
163 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
164 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
165 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
166
167 m_faceTable.add(face);
168
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000169 ControlParameters response = collectFaceProperties(*face, true);
Eric Newberry42602412016-08-27 09:33:18 -0700170 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
171}
172
173void
174FaceManager::afterCreateFaceFailure(uint32_t status,
175 const std::string& reason,
176 const ndn::mgmt::CommandContinuation& done)
177{
178 NFD_LOG_DEBUG("Face creation failed: " << reason);
179
180 done(ControlResponse(status, reason));
Yanbiao Li73860e32015-08-19 16:30:16 -0700181}
182
183void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700184FaceManager::updateFace(const Name& topPrefix, const Interest& interest,
185 const ControlParameters& parameters,
186 const ndn::mgmt::CommandContinuation& done)
187{
188 FaceId faceId = parameters.getFaceId();
189 if (faceId == 0) {
190 // Self-updating
191 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
192 if (incomingFaceIdTag == nullptr) {
193 NFD_LOG_TRACE("unable to determine face for self-update");
194 done(ControlResponse(404, "No FaceId specified and IncomingFaceId not available"));
195 return;
196 }
197 faceId = *incomingFaceIdTag;
198 }
199
200 Face* face = m_faceTable.get(faceId);
201
202 if (face == nullptr) {
203 NFD_LOG_TRACE("invalid face specified");
204 done(ControlResponse(404, "Specified face does not exist"));
205 return;
206 }
207
208 // Verify validity of requested changes
209 ControlParameters response;
210 bool areParamsValid = true;
211
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700212 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
213 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
214 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
215 NFD_LOG_TRACE("received request to enable local fields on non-local face");
216 areParamsValid = false;
217 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
218 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
219 }
220
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000221 // check whether the requested FacePersistency change is valid if it's present
222 if (parameters.hasFacePersistency()) {
223 auto persistency = parameters.getFacePersistency();
224 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
225 NFD_LOG_TRACE("cannot change face persistency to " << persistency);
226 areParamsValid = false;
227 response.setFacePersistency(persistency);
228 }
229 }
230
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700231 if (!areParamsValid) {
232 done(ControlResponse(409, "Invalid properties specified").setBody(response.wireEncode()));
233 return;
234 }
235
236 // All specified properties are valid, so make changes
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000237 if (parameters.hasFacePersistency()) {
238 face->setPersistency(parameters.getFacePersistency());
239 }
Eric Newberry2642cd22017-07-13 21:34:53 -0400240 setLinkServiceOptions(*face, parameters);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700241
Eric Newberryf40551a2016-09-05 15:41:16 -0700242 // Set ControlResponse fields
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000243 response = collectFaceProperties(*face, false);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700244
245 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
246}
247
248void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700249FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
250 const ControlParameters& parameters,
251 const ndn::mgmt::CommandContinuation& done)
252{
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000253 Face* face = m_faceTable.get(parameters.getFaceId());
254 if (face != nullptr) {
255 face->close();
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700256 }
257
258 done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
259}
260
261void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700262FaceManager::setLinkServiceOptions(Face& face,
Eric Newberry2642cd22017-07-13 21:34:53 -0400263 const ControlParameters& parameters)
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700264{
265 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
266 BOOST_ASSERT(linkService != nullptr);
267
268 auto options = linkService->getOptions();
269 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
270 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
271 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
272 }
Eric Newberry2642cd22017-07-13 21:34:53 -0400273 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
274 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
275 }
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700276 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
277 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
278 }
279 if (parameters.hasBaseCongestionMarkingInterval()) {
280 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
281 }
282 if (parameters.hasDefaultCongestionThreshold()) {
283 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
284 }
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700285 linkService->setOptions(options);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700286}
287
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000288ControlParameters
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000289FaceManager::collectFaceProperties(const Face& face, bool wantUris)
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000290{
291 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
292 BOOST_ASSERT(linkService != nullptr);
293 auto options = linkService->getOptions();
294
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000295 ControlParameters params;
296 params.setFaceId(face.getId())
297 .setFacePersistency(face.getPersistency())
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700298 .setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
299 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
Eric Newberry2642cd22017-07-13 21:34:53 -0400300 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false)
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700301 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled, false)
302 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking, false);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000303 if (wantUris) {
304 params.setUri(face.getRemoteUri().toString())
305 .setLocalUri(face.getLocalUri().toString());
306 }
307 return params;
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000308}
309
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700310void
Yanbiao Li73860e32015-08-19 16:30:16 -0700311FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
312 ndn::mgmt::StatusDatasetContext& context)
313{
Eric Newberryc64d30a2015-12-26 11:07:27 -0700314 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000315 for (const Face& face : m_faceTable) {
316 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700317 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700318 }
319 context.end();
320}
321
322void
323FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
324 ndn::mgmt::StatusDatasetContext& context)
325{
Davide Pesaventoe5eebad2017-04-06 20:23:26 -0400326 std::set<const face::ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
327 for (const auto* factory : factories) {
Junxiao Shib8590312016-12-29 21:22:25 +0000328 for (const auto& channel : factory->getChannels()) {
329 ndn::nfd::ChannelStatus entry;
330 entry.setLocalUri(channel->getUri().toString());
331 context.append(entry.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700332 }
333 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700334 context.end();
335}
336
337void
338FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
339 ndn::mgmt::StatusDatasetContext& context)
340{
341 ndn::nfd::FaceQueryFilter faceFilter;
342 const Name& query = interest.getName();
343 try {
344 faceFilter.wireDecode(query[-1].blockFromValue());
345 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200346 catch (const tlv::Error& e) {
347 NFD_LOG_DEBUG("Malformed query filter: " << e.what());
348 return context.reject(ControlResponse(400, "Malformed filter"));
Yanbiao Li73860e32015-08-19 16:30:16 -0700349 }
350
Eric Newberryc64d30a2015-12-26 11:07:27 -0700351 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000352 for (const Face& face : m_faceTable) {
353 if (!matchFilter(faceFilter, face)) {
Junxiao Shida93f1f2015-11-11 06:13:16 -0700354 continue;
Yanbiao Li73860e32015-08-19 16:30:16 -0700355 }
Junxiao Shib84e6742016-07-19 13:16:22 +0000356 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700357 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700358 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200359
Yanbiao Li73860e32015-08-19 16:30:16 -0700360 context.end();
361}
362
363bool
Junxiao Shib84e6742016-07-19 13:16:22 +0000364FaceManager::matchFilter(const ndn::nfd::FaceQueryFilter& filter, const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700365{
366 if (filter.hasFaceId() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000367 filter.getFaceId() != static_cast<uint64_t>(face.getId())) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700368 return false;
369 }
370
371 if (filter.hasUriScheme() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000372 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
373 filter.getUriScheme() != face.getLocalUri().getScheme()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700374 return false;
375 }
376
377 if (filter.hasRemoteUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000378 filter.getRemoteUri() != face.getRemoteUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700379 return false;
380 }
381
382 if (filter.hasLocalUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000383 filter.getLocalUri() != face.getLocalUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700384 return false;
385 }
386
387 if (filter.hasFaceScope() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000388 filter.getFaceScope() != face.getScope()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700389 return false;
390 }
391
392 if (filter.hasFacePersistency() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000393 filter.getFacePersistency() != face.getPersistency()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700394 return false;
395 }
396
397 if (filter.hasLinkType() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000398 filter.getLinkType() != face.getLinkType()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700399 return false;
400 }
401
402 return true;
403}
404
Eric Newberryc64d30a2015-12-26 11:07:27 -0700405ndn::nfd::FaceStatus
406FaceManager::collectFaceStatus(const Face& face, const time::steady_clock::TimePoint& now)
407{
408 ndn::nfd::FaceStatus status;
409
410 collectFaceProperties(face, status);
411
412 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
413 if (expirationTime != time::steady_clock::TimePoint::max()) {
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700414 status.setExpirationPeriod(std::max(0_ms,
Eric Newberryc64d30a2015-12-26 11:07:27 -0700415 time::duration_cast<time::milliseconds>(expirationTime - now)));
416 }
417
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700418 // Get LinkService options
419 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
420 if (linkService != nullptr) {
421 auto linkServiceOptions = linkService->getOptions();
422 status.setBaseCongestionMarkingInterval(linkServiceOptions.baseCongestionMarkingInterval);
423 status.setDefaultCongestionThreshold(linkServiceOptions.defaultCongestionThreshold);
424 }
425
Eric Newberryc64d30a2015-12-26 11:07:27 -0700426 const face::FaceCounters& counters = face.getCounters();
427 status.setNInInterests(counters.nInInterests)
428 .setNOutInterests(counters.nOutInterests)
Junxiao Shif03d4792017-04-06 16:41:22 +0000429 .setNInData(counters.nInData)
430 .setNOutData(counters.nOutData)
Eric Newberryc64d30a2015-12-26 11:07:27 -0700431 .setNInNacks(counters.nInNacks)
432 .setNOutNacks(counters.nOutNacks)
433 .setNInBytes(counters.nInBytes)
434 .setNOutBytes(counters.nOutBytes);
435
436 return status;
437}
438
Junxiao Shida93f1f2015-11-11 06:13:16 -0700439template<typename FaceTraits>
Junxiao Shicde37ad2015-12-24 01:02:05 -0700440void
441FaceManager::collectFaceProperties(const Face& face, FaceTraits& traits)
Junxiao Shida93f1f2015-11-11 06:13:16 -0700442{
443 traits.setFaceId(face.getId())
444 .setRemoteUri(face.getRemoteUri().toString())
445 .setLocalUri(face.getLocalUri().toString())
446 .setFaceScope(face.getScope())
447 .setFacePersistency(face.getPersistency())
448 .setLinkType(face.getLinkType());
Eric Newberry1b4ba052016-10-07 23:04:07 -0700449
450 // Set Flag bits
451 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
452 if (linkService != nullptr) {
453 auto linkServiceOptions = linkService->getOptions();
454 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400455 traits.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED,
456 linkServiceOptions.reliabilityOptions.isEnabled);
Eric Newberryde332452018-01-30 11:45:32 -0700457 traits.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED,
458 linkServiceOptions.allowCongestionMarking);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700459 }
Junxiao Shida93f1f2015-11-11 06:13:16 -0700460}
461
462void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700463FaceManager::notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind)
Yanbiao Li73860e32015-08-19 16:30:16 -0700464{
465 ndn::nfd::FaceEventNotification notification;
Eric Newberry1b4ba052016-10-07 23:04:07 -0700466 notification.setKind(kind);
Junxiao Shiae04d342016-07-19 13:20:22 +0000467 collectFaceProperties(face, notification);
Yanbiao Li73860e32015-08-19 16:30:16 -0700468
Junxiao Shiae04d342016-07-19 13:20:22 +0000469 m_postNotification(notification.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700470}
471
472void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700473FaceManager::connectFaceStateChangeSignal(const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700474{
Eric Newberry1b4ba052016-10-07 23:04:07 -0700475 FaceId faceId = face.getId();
476 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
477 [this, faceId] (face::FaceState oldState, face::FaceState newState) {
478 const Face& face = *m_faceTable.get(faceId);
Yanbiao Li73860e32015-08-19 16:30:16 -0700479
Eric Newberry1b4ba052016-10-07 23:04:07 -0700480 if (newState == face::FaceState::UP) {
481 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
482 }
483 else if (newState == face::FaceState::DOWN) {
484 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
485 }
486 else if (newState == face::FaceState::CLOSED) {
487 m_faceStateChangeConn.erase(faceId);
488 }
489 });
Yanbiao Li73860e32015-08-19 16:30:16 -0700490}
491
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200492} // namespace nfd