blob: 23e2ce2dfe2037b410384cddf6904e6295237a1d [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 try {
Eric Newberrya1939ba2015-10-09 12:35:03 -0700123 lp::Packet pkt(packet.packet);
124
125 if (!pkt.has<lp::FragmentField>()) {
126 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
127 return;
128 }
129
130 if (pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) {
131 NFD_LOG_FACE_WARN("received fragment, but reassembly not implemented: DROP");
132 return;
133 }
134
Eric Newberry86d31872015-09-23 16:24:59 -0700135 ndn::Buffer::const_iterator fragBegin, fragEnd;
136 std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
137 Block netPkt(&*fragBegin, std::distance(fragBegin, fragEnd));
138
139 switch (netPkt.type()) {
140 case tlv::Interest:
141 if (pkt.has<lp::NackField>()) {
142 this->decodeNack(netPkt, pkt);
143 }
144 else {
145 this->decodeInterest(netPkt, pkt);
146 }
147 break;
148 case tlv::Data:
149 this->decodeData(netPkt, pkt);
150 break;
151 default:
152 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
153 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700154 }
155 }
Eric Newberry86d31872015-09-23 16:24:59 -0700156 catch (const tlv::Error& e) {
157 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
158 }
159}
160
161
162void
163GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt)
164{
165 BOOST_ASSERT(netPkt.type() == tlv::Interest);
166 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
167
168 // forwarding expects Interest to be created with make_shared
169 auto interest = make_shared<Interest>(netPkt);
170
171 if (firstPkt.has<lp::NextHopFaceIdField>()) {
172 if (m_options.allowLocalFields) {
173 interest->setNextHopFaceId(firstPkt.get<lp::NextHopFaceIdField>());
174 }
175 else {
176 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
177 return;
178 }
179 }
180
181 if (firstPkt.has<lp::CachePolicyField>()) {
182 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
183 return;
184 }
185
186 if (firstPkt.has<lp::IncomingFaceIdField>()) {
187 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
188 }
189
190 this->receiveInterest(*interest);
191}
192
193void
194GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
195{
196 BOOST_ASSERT(netPkt.type() == tlv::Data);
197
198 // forwarding expects Data to be created with make_shared
199 auto data = make_shared<Data>(netPkt);
200
201 if (firstPkt.has<lp::NackField>()) {
202 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
203 return;
204 }
205
206 if (firstPkt.has<lp::NextHopFaceIdField>()) {
207 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
208 return;
209 }
210
211 if (firstPkt.has<lp::CachePolicyField>()) {
212 if (m_options.allowLocalFields) {
213 lp::CachePolicyType policy = firstPkt.get<lp::CachePolicyField>().getPolicy();
214 switch (policy) {
215 case lp::CachePolicyType::NO_CACHE:
216 data->setCachingPolicy(ndn::nfd::LocalControlHeader::CachingPolicy::NO_CACHE);
217 break;
218 default:
219 NFD_LOG_FACE_WARN("unrecognized CachePolicyType " << policy << ": DROP");
220 return;
221 }
222 }
223 else {
224 NFD_LOG_FACE_WARN("received CachePolicy, but local fields disabled: IGNORE");
225 }
226 }
227
228 if (firstPkt.has<lp::IncomingFaceIdField>()) {
229 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
230 }
231
232 this->receiveData(*data);
233}
234
235void
236GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt)
237{
238 BOOST_ASSERT(netPkt.type() == tlv::Interest);
239 BOOST_ASSERT(firstPkt.has<lp::NackField>());
240
241 lp::Nack nack((Interest(netPkt)));
242 nack.setHeader(firstPkt.get<lp::NackField>());
243
244 if (firstPkt.has<lp::NextHopFaceIdField>()) {
245 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
246 return;
247 }
248
249 if (firstPkt.has<lp::CachePolicyField>()) {
250 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
251 return;
252 }
253
254 if (firstPkt.has<lp::IncomingFaceIdField>()) {
255 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
256 }
257
258 this->receiveNack(nack);
Eric Newberrya98bf932015-09-21 00:58:47 -0700259}
260
261} // namespace face
262} // namespace nfd