blob: 4fa4c1c99f2295b62a8c83293f2fc19df09a45c7 [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * 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.
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 "generic-link-service.hpp"
27
28namespace nfd {
29namespace face {
30
31NFD_LOG_INIT("GenericLinkService");
32
Eric Newberry86d31872015-09-23 16:24:59 -070033GenericLinkService::Options::Options()
34 : allowLocalFields(false)
35{
36}
37
38GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
39 : m_options(options)
40{
41}
42
Eric Newberrya98bf932015-09-21 00:58:47 -070043void
44GenericLinkService::doSendInterest(const Interest& interest)
45{
46 lp::Packet lpPacket(interest.wireEncode());
Eric Newberry86d31872015-09-23 16:24:59 -070047 if (m_options.allowLocalFields) {
48 encodeLocalFields(interest, lpPacket);
49 }
Eric Newberrya98bf932015-09-21 00:58:47 -070050 Transport::Packet packet;
51 packet.packet = lpPacket.wireEncode();
52 sendPacket(std::move(packet));
53}
54
55void
56GenericLinkService::doSendData(const Data& data)
57{
58 lp::Packet lpPacket(data.wireEncode());
Eric Newberry86d31872015-09-23 16:24:59 -070059 if (m_options.allowLocalFields) {
60 encodeLocalFields(data, lpPacket);
61 }
Eric Newberrya98bf932015-09-21 00:58:47 -070062 Transport::Packet packet;
63 packet.packet = lpPacket.wireEncode();
64 sendPacket(std::move(packet));
65}
66
67void
68GenericLinkService::doSendNack(const lp::Nack& nack)
69{
70 lp::Packet lpPacket(nack.getInterest().wireEncode());
71 lpPacket.add<lp::NackField>(nack.getHeader());
Eric Newberry86d31872015-09-23 16:24:59 -070072 if (m_options.allowLocalFields) {
73 encodeLocalFields(nack.getInterest(), lpPacket);
74 }
Eric Newberrya98bf932015-09-21 00:58:47 -070075 Transport::Packet packet;
76 packet.packet = lpPacket.wireEncode();
77 sendPacket(std::move(packet));
78}
79
Eric Newberry86d31872015-09-23 16:24:59 -070080bool
81GenericLinkService::encodeLocalFields(const Interest& interest, lp::Packet& lpPacket)
82{
83 if (interest.getLocalControlHeader().hasIncomingFaceId()) {
84 lpPacket.add<lp::IncomingFaceIdField>(interest.getIncomingFaceId());
85 }
86
87 if (interest.getLocalControlHeader().hasCachingPolicy()) {
88 // Packet must be dropped
89 return false;
90 }
91
92 return true;
93}
94
95bool
96GenericLinkService::encodeLocalFields(const Data& data, lp::Packet& lpPacket)
97{
98 if (data.getLocalControlHeader().hasIncomingFaceId()) {
99 lpPacket.add<lp::IncomingFaceIdField>(data.getIncomingFaceId());
100 }
101
102 if (data.getLocalControlHeader().hasCachingPolicy()) {
103 switch (data.getCachingPolicy()) {
104 case ndn::nfd::LocalControlHeader::CachingPolicy::NO_CACHE: {
105 lp::CachePolicy cachePolicy;
106 cachePolicy.setPolicy(lp::CachePolicyType::NO_CACHE);
107 lpPacket.add<lp::CachePolicyField>(cachePolicy);
108 break;
109 }
110 default: {
111 break;
112 }
113 }
114 }
115
116 return true;
117}
118
Eric Newberrya98bf932015-09-21 00:58:47 -0700119void
120GenericLinkService::doReceivePacket(Transport::Packet&& packet)
121{
Eric Newberry86d31872015-09-23 16:24:59 -0700122 lp::Packet pkt(packet.packet);
Eric Newberrya98bf932015-09-21 00:58:47 -0700123
Eric Newberry86d31872015-09-23 16:24:59 -0700124 if (pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) {
125 NFD_LOG_FACE_WARN("received fragment, but reassembly not implemented: DROP");
126 return;
127 }
128
129 try {
130 ndn::Buffer::const_iterator fragBegin, fragEnd;
131 std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
132 Block netPkt(&*fragBegin, std::distance(fragBegin, fragEnd));
133
134 switch (netPkt.type()) {
135 case tlv::Interest:
136 if (pkt.has<lp::NackField>()) {
137 this->decodeNack(netPkt, pkt);
138 }
139 else {
140 this->decodeInterest(netPkt, pkt);
141 }
142 break;
143 case tlv::Data:
144 this->decodeData(netPkt, pkt);
145 break;
146 default:
147 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
148 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700149 }
150 }
Eric Newberry86d31872015-09-23 16:24:59 -0700151 catch (const tlv::Error& e) {
152 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
153 }
154}
155
156
157void
158GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt)
159{
160 BOOST_ASSERT(netPkt.type() == tlv::Interest);
161 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
162
163 // forwarding expects Interest to be created with make_shared
164 auto interest = make_shared<Interest>(netPkt);
165
166 if (firstPkt.has<lp::NextHopFaceIdField>()) {
167 if (m_options.allowLocalFields) {
168 interest->setNextHopFaceId(firstPkt.get<lp::NextHopFaceIdField>());
169 }
170 else {
171 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
172 return;
173 }
174 }
175
176 if (firstPkt.has<lp::CachePolicyField>()) {
177 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
178 return;
179 }
180
181 if (firstPkt.has<lp::IncomingFaceIdField>()) {
182 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
183 }
184
185 this->receiveInterest(*interest);
186}
187
188void
189GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
190{
191 BOOST_ASSERT(netPkt.type() == tlv::Data);
192
193 // forwarding expects Data to be created with make_shared
194 auto data = make_shared<Data>(netPkt);
195
196 if (firstPkt.has<lp::NackField>()) {
197 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
198 return;
199 }
200
201 if (firstPkt.has<lp::NextHopFaceIdField>()) {
202 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
203 return;
204 }
205
206 if (firstPkt.has<lp::CachePolicyField>()) {
207 if (m_options.allowLocalFields) {
208 lp::CachePolicyType policy = firstPkt.get<lp::CachePolicyField>().getPolicy();
209 switch (policy) {
210 case lp::CachePolicyType::NO_CACHE:
211 data->setCachingPolicy(ndn::nfd::LocalControlHeader::CachingPolicy::NO_CACHE);
212 break;
213 default:
214 NFD_LOG_FACE_WARN("unrecognized CachePolicyType " << policy << ": DROP");
215 return;
216 }
217 }
218 else {
219 NFD_LOG_FACE_WARN("received CachePolicy, but local fields disabled: IGNORE");
220 }
221 }
222
223 if (firstPkt.has<lp::IncomingFaceIdField>()) {
224 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
225 }
226
227 this->receiveData(*data);
228}
229
230void
231GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt)
232{
233 BOOST_ASSERT(netPkt.type() == tlv::Interest);
234 BOOST_ASSERT(firstPkt.has<lp::NackField>());
235
236 lp::Nack nack((Interest(netPkt)));
237 nack.setHeader(firstPkt.get<lp::NackField>());
238
239 if (firstPkt.has<lp::NextHopFaceIdField>()) {
240 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
241 return;
242 }
243
244 if (firstPkt.has<lp::CachePolicyField>()) {
245 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
246 return;
247 }
248
249 if (firstPkt.has<lp::IncomingFaceIdField>()) {
250 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
251 }
252
253 this->receiveNack(nack);
Eric Newberrya98bf932015-09-21 00:58:47 -0700254}
255
256} // namespace face
257} // namespace nfd