blob: f13cf9bcc603ee2857871b63314acf30e42bbecc [file] [log] [blame]
Alexander Afanasyevbd220a02014-02-20 00:29:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Alexander Afanasyev319f2c82015-01-07 14:56:53 -080024 */
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_FACE_LOCAL_FACE_HPP
27#define NFD_DAEMON_FACE_LOCAL_FACE_HPP
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080028
29#include "face.hpp"
Alexander Afanasyev4a771362014-04-24 21:29:33 -070030#include <ndn-cxx/management/nfd-control-parameters.hpp>
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080031
32namespace nfd {
33
Steve DiBenedetto7564d972014-03-24 14:28:46 -060034using ndn::nfd::LocalControlFeature;
35using ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID;
36using ndn::nfd::LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080037
38/** \brief represents a face
39 */
40class LocalFace : public Face
41{
42public:
Junxiao Shi79494162014-04-02 18:25:11 -070043 LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080044
Steve DiBenedetto7564d972014-03-24 14:28:46 -060045 /** \brief get whether any LocalControlHeader feature is enabled
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080046 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060047 * \returns true if any feature is enabled.
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080048 */
49 bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060050 isLocalControlHeaderEnabled() const;
51
52 /** \brief get whether a specific LocalControlHeader feature is enabled
53 *
54 * \param feature The feature.
55 * \returns true if the specified feature is enabled.
56 */
57 bool
58 isLocalControlHeaderEnabled(LocalControlFeature feature) const;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080059
60 /** \brief enable or disable a LocalControlHeader feature
61 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060062 * \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
63 * or LOCAL_CONTROL_FEATURE_MAX
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -050064 * \param enabled true/false enable/disable the feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080065 */
66 void
Steve DiBenedetto7564d972014-03-24 14:28:46 -060067 setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
68
69public:
70
71 static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
72 static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080073
74protected:
75 // statically overridden from Face
76
77 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
78 *
79 * If LocalControlHeader is present, the encoded data is filtered out, based
80 * on enabled features on the face.
81 */
82 bool
83 decodeAndDispatchInput(const Block& element);
84
85 // LocalFace-specific methods
86
87 /** \brief Check if LocalControlHeader needs to be included, taking into account
88 * both set parameters in supplied LocalControlHeader and features
89 * enabled on the local face.
90 */
91 bool
92 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
93
94 /** \brief Create LocalControlHeader, considering enabled features
95 */
96 template<class Packet>
97 Block
98 filterAndEncodeLocalControlHeader(const Packet& packet);
99
100private:
101 std::vector<bool> m_localControlHeaderFeatures;
102};
103
104inline
Junxiao Shi79494162014-04-02 18:25:11 -0700105LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
106 : Face(remoteUri, localUri, true)
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600107 , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800108{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800109}
110
111inline bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600112LocalFace::isLocalControlHeaderEnabled() const
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800113{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600114 return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
115}
116
117inline bool
118LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
119{
Alexander Afanasyev85b6b012014-04-21 18:12:57 -0700120 BOOST_ASSERT(0 < feature &&
121 static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800122 return m_localControlHeaderFeatures[feature];
123}
124
125inline void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600126LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800127{
Alexander Afanasyev85b6b012014-04-21 18:12:57 -0700128 BOOST_ASSERT(0 < feature &&
129 static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600130
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800131 m_localControlHeaderFeatures[feature] = enabled;
132
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600133 m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800134 std::find(m_localControlHeaderFeatures.begin() + 1,
135 m_localControlHeaderFeatures.end(), true) <
136 m_localControlHeaderFeatures.end();
137 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
138}
139
140inline bool
141LocalFace::decodeAndDispatchInput(const Block& element)
142{
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700143 try {
144 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800145
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700146 // If received LocalControlHeader, but it is not enabled on the face
147 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
148 return false;
149
150 if (payload.type() == tlv::Interest)
151 {
152 shared_ptr<Interest> i = make_shared<Interest>();
153 i->wireDecode(payload);
154 if (&payload != &element)
155 {
Alexander Afanasyeva4ff44c2015-02-13 14:11:37 -0800156 uint8_t mask = 0;
157 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID)) {
158 mask |= ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP;
159 }
160 i->getLocalControlHeader().wireDecode(element, mask);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700161 }
162
Junxiao Shic099ddb2014-12-25 20:53:20 -0700163 this->emitSignal(onReceiveInterest, *i);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700164 }
165 else if (payload.type() == tlv::Data)
166 {
167 shared_ptr<Data> d = make_shared<Data>();
168 d->wireDecode(payload);
169
170 /// \todo Uncomment and correct the following when we have more
171 /// options in LocalControlHeader that apply for incoming
172 /// Data packets (if ever)
173 // if (&payload != &element)
174 // {
175 //
176 // d->getLocalControlHeader().wireDecode(element,
177 // false,
178 // false);
179 // }
180
Junxiao Shic099ddb2014-12-25 20:53:20 -0700181 this->emitSignal(onReceiveData, *d);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700182 }
183 else
184 return false;
185
186 return true;
187 }
Davide Pesavento66ff0982015-01-29 22:39:00 +0100188 catch (const tlv::Error&) {
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800189 return false;
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700190 }
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800191}
192
193inline bool
194LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
195{
196 if (!this->isLocalControlHeaderEnabled())
197 return true;
198
Alexander Afanasyeva4ff44c2015-02-13 14:11:37 -0800199 uint8_t mask = 0;
200 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
201 mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
202 }
203 return header.empty(mask);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800204}
205
206template<class Packet>
207inline Block
208LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
209{
Alexander Afanasyeva4ff44c2015-02-13 14:11:37 -0800210 uint8_t mask = 0;
211 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
212 mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
213 }
214 return packet.getLocalControlHeader().wireEncode(packet, mask);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800215}
216
217} // namespace nfd
218
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700219#endif // NFD_DAEMON_FACE_LOCAL_FACE_HPP