blob: 5f2eb0d790266db62a5b7a5d89a59dd52cbf7ebe [file] [log] [blame]
Alexander Afanasyevbd220a02014-02-20 00:29:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080024
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070025#ifndef NFD_DAEMON_FACE_LOCAL_FACE_HPP
26#define NFD_DAEMON_FACE_LOCAL_FACE_HPP
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080027
28#include "face.hpp"
Alexander Afanasyev4a771362014-04-24 21:29:33 -070029#include <ndn-cxx/management/nfd-control-parameters.hpp>
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080030
31namespace nfd {
32
Steve DiBenedetto7564d972014-03-24 14:28:46 -060033using ndn::nfd::LocalControlFeature;
34using ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID;
35using ndn::nfd::LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080036
37/** \brief represents a face
38 */
39class LocalFace : public Face
40{
41public:
Junxiao Shi79494162014-04-02 18:25:11 -070042 LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080043
Steve DiBenedetto7564d972014-03-24 14:28:46 -060044 /** \brief get whether any LocalControlHeader feature is enabled
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080045 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060046 * \returns true if any feature is enabled.
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080047 */
48 bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060049 isLocalControlHeaderEnabled() const;
50
51 /** \brief get whether a specific LocalControlHeader feature is enabled
52 *
53 * \param feature The feature.
54 * \returns true if the specified feature is enabled.
55 */
56 bool
57 isLocalControlHeaderEnabled(LocalControlFeature feature) const;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080058
59 /** \brief enable or disable a LocalControlHeader feature
60 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060061 * \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
62 * or LOCAL_CONTROL_FEATURE_MAX
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080063 */
64 void
Steve DiBenedetto7564d972014-03-24 14:28:46 -060065 setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
66
67public:
68
69 static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
70 static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080071
72protected:
73 // statically overridden from Face
74
75 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
76 *
77 * If LocalControlHeader is present, the encoded data is filtered out, based
78 * on enabled features on the face.
79 */
80 bool
81 decodeAndDispatchInput(const Block& element);
82
83 // LocalFace-specific methods
84
85 /** \brief Check if LocalControlHeader needs to be included, taking into account
86 * both set parameters in supplied LocalControlHeader and features
87 * enabled on the local face.
88 */
89 bool
90 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
91
92 /** \brief Create LocalControlHeader, considering enabled features
93 */
94 template<class Packet>
95 Block
96 filterAndEncodeLocalControlHeader(const Packet& packet);
97
98private:
99 std::vector<bool> m_localControlHeaderFeatures;
100};
101
102inline
Junxiao Shi79494162014-04-02 18:25:11 -0700103LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
104 : Face(remoteUri, localUri, true)
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600105 , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800106{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800107}
108
109inline bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600110LocalFace::isLocalControlHeaderEnabled() const
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800111{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600112 return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
113}
114
115inline bool
116LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
117{
Alexander Afanasyev85b6b012014-04-21 18:12:57 -0700118 BOOST_ASSERT(0 < feature &&
119 static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800120 return m_localControlHeaderFeatures[feature];
121}
122
123inline void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600124LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800125{
Alexander Afanasyev85b6b012014-04-21 18:12:57 -0700126 BOOST_ASSERT(0 < feature &&
127 static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600128
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800129 m_localControlHeaderFeatures[feature] = enabled;
130
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600131 m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800132 std::find(m_localControlHeaderFeatures.begin() + 1,
133 m_localControlHeaderFeatures.end(), true) <
134 m_localControlHeaderFeatures.end();
135 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
136}
137
138inline bool
139LocalFace::decodeAndDispatchInput(const Block& element)
140{
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700141 try {
142 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800143
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700144 // If received LocalControlHeader, but it is not enabled on the face
145 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
146 return false;
147
148 if (payload.type() == tlv::Interest)
149 {
150 shared_ptr<Interest> i = make_shared<Interest>();
151 i->wireDecode(payload);
152 if (&payload != &element)
153 {
Alexander Afanasyev8f5a99d2015-02-13 15:07:06 -0800154 uint8_t mask = 0;
155 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID)) {
156 mask |= ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP;
157 }
158 i->getLocalControlHeader().wireDecode(element, mask);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700159 }
160
161 this->onReceiveInterest(*i);
162 }
163 else if (payload.type() == tlv::Data)
164 {
165 shared_ptr<Data> d = make_shared<Data>();
166 d->wireDecode(payload);
167
168 /// \todo Uncomment and correct the following when we have more
169 /// options in LocalControlHeader that apply for incoming
170 /// Data packets (if ever)
171 // if (&payload != &element)
172 // {
173 //
174 // d->getLocalControlHeader().wireDecode(element,
175 // false,
176 // false);
177 // }
178
179 this->onReceiveData(*d);
180 }
181 else
182 return false;
183
184 return true;
185 }
186 catch (tlv::Error&) {
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800187 return false;
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700188 }
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800189}
190
191inline bool
192LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
193{
194 if (!this->isLocalControlHeaderEnabled())
195 return true;
196
Alexander Afanasyev8f5a99d2015-02-13 15:07:06 -0800197 uint8_t mask = 0;
198 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
199 mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
200 }
201 return header.empty(mask);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800202}
203
204template<class Packet>
205inline Block
206LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
207{
Alexander Afanasyev8f5a99d2015-02-13 15:07:06 -0800208 uint8_t mask = 0;
209 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
210 mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
211 }
212 return packet.getLocalControlHeader().wireEncode(packet, mask);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800213}
214
215} // namespace nfd
216
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700217#endif // NFD_DAEMON_FACE_LOCAL_FACE_HPP