blob: e2bf4790e7821884f27bb0fc99a75d133a856eaf [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 Afanasyevbd220a02014-02-20 00:29:56 -080064 */
65 void
Steve DiBenedetto7564d972014-03-24 14:28:46 -060066 setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
67
68public:
69
70 static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
71 static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080072
73protected:
74 // statically overridden from Face
75
76 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
77 *
78 * If LocalControlHeader is present, the encoded data is filtered out, based
79 * on enabled features on the face.
80 */
81 bool
82 decodeAndDispatchInput(const Block& element);
83
84 // LocalFace-specific methods
85
86 /** \brief Check if LocalControlHeader needs to be included, taking into account
87 * both set parameters in supplied LocalControlHeader and features
88 * enabled on the local face.
89 */
90 bool
91 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
92
93 /** \brief Create LocalControlHeader, considering enabled features
94 */
95 template<class Packet>
96 Block
97 filterAndEncodeLocalControlHeader(const Packet& packet);
98
99private:
100 std::vector<bool> m_localControlHeaderFeatures;
101};
102
103inline
Junxiao Shi79494162014-04-02 18:25:11 -0700104LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
105 : Face(remoteUri, localUri, true)
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600106 , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800107{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800108}
109
110inline bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600111LocalFace::isLocalControlHeaderEnabled() const
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800112{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600113 return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
114}
115
116inline bool
117LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
118{
Alexander Afanasyev85b6b012014-04-21 18:12:57 -0700119 BOOST_ASSERT(0 < feature &&
120 static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800121 return m_localControlHeaderFeatures[feature];
122}
123
124inline void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600125LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800126{
Alexander Afanasyev85b6b012014-04-21 18:12:57 -0700127 BOOST_ASSERT(0 < feature &&
128 static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600129
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800130 m_localControlHeaderFeatures[feature] = enabled;
131
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600132 m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800133 std::find(m_localControlHeaderFeatures.begin() + 1,
134 m_localControlHeaderFeatures.end(), true) <
135 m_localControlHeaderFeatures.end();
136 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
137}
138
139inline bool
140LocalFace::decodeAndDispatchInput(const Block& element)
141{
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700142 try {
143 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800144
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700145 // If received LocalControlHeader, but it is not enabled on the face
146 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
147 return false;
148
149 if (payload.type() == tlv::Interest)
150 {
151 shared_ptr<Interest> i = make_shared<Interest>();
152 i->wireDecode(payload);
153 if (&payload != &element)
154 {
Alexander Afanasyeva4ff44c2015-02-13 14:11:37 -0800155 uint8_t mask = 0;
156 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID)) {
157 mask |= ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP;
158 }
159 i->getLocalControlHeader().wireDecode(element, mask);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700160 }
161
Junxiao Shic099ddb2014-12-25 20:53:20 -0700162 this->emitSignal(onReceiveInterest, *i);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700163 }
164 else if (payload.type() == tlv::Data)
165 {
166 shared_ptr<Data> d = make_shared<Data>();
167 d->wireDecode(payload);
168
169 /// \todo Uncomment and correct the following when we have more
170 /// options in LocalControlHeader that apply for incoming
171 /// Data packets (if ever)
172 // if (&payload != &element)
173 // {
174 //
175 // d->getLocalControlHeader().wireDecode(element,
176 // false,
177 // false);
178 // }
179
Junxiao Shic099ddb2014-12-25 20:53:20 -0700180 this->emitSignal(onReceiveData, *d);
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700181 }
182 else
183 return false;
184
185 return true;
186 }
Davide Pesavento66ff0982015-01-29 22:39:00 +0100187 catch (const tlv::Error&) {
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800188 return false;
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700189 }
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800190}
191
192inline bool
193LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
194{
195 if (!this->isLocalControlHeaderEnabled())
196 return true;
197
Alexander Afanasyeva4ff44c2015-02-13 14:11:37 -0800198 uint8_t mask = 0;
199 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
200 mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
201 }
202 return header.empty(mask);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800203}
204
205template<class Packet>
206inline Block
207LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
208{
Alexander Afanasyeva4ff44c2015-02-13 14:11:37 -0800209 uint8_t mask = 0;
210 if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
211 mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
212 }
213 return packet.getLocalControlHeader().wireEncode(packet, mask);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800214}
215
216} // namespace nfd
217
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700218#endif // NFD_DAEMON_FACE_LOCAL_FACE_HPP