NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
segment-fetcher.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "segment-fetcher.hpp"
23 #include "../encoding/buffer-stream.hpp"
24 #include "../name-component.hpp"
25 #include "../lp/nack.hpp"
26 #include "../lp/nack-header.hpp"
27 
28 namespace ndn {
29 namespace util {
30 
32 
33 SegmentFetcher::SegmentFetcher(Face& face,
34  shared_ptr<Validator> validator,
35  const CompleteCallback& completeCallback,
36  const ErrorCallback& errorCallback)
37  : m_face(face)
38  , m_scheduler(m_face.getIoService())
39  , m_validator(validator)
40  , m_completeCallback(completeCallback)
41  , m_errorCallback(errorCallback)
42  , m_buffer(make_shared<OBufferStream>())
43 {
44 }
45 
46 void
48  const Interest& baseInterest,
49  Validator& validator,
50  const CompleteCallback& completeCallback,
51  const ErrorCallback& errorCallback)
52 {
53  shared_ptr<Validator> sharedValidator = shared_ptr<Validator>(&validator, [] (Validator*) {});
54 
55  fetch(face, baseInterest, sharedValidator, completeCallback, errorCallback);
56 }
57 
58 void
60  const Interest& baseInterest,
61  shared_ptr<Validator> validator,
62  const CompleteCallback& completeCallback,
63  const ErrorCallback& errorCallback)
64 {
65  shared_ptr<SegmentFetcher> fetcher(new SegmentFetcher(face, validator, completeCallback,
66  errorCallback));
67 
68  fetcher->fetchFirstSegment(baseInterest, fetcher);
69 }
70 
71 void
72 SegmentFetcher::fetchFirstSegment(const Interest& baseInterest,
73  shared_ptr<SegmentFetcher> self)
74 {
75  Interest interest(baseInterest);
76  interest.setChildSelector(1);
77  interest.setMustBeFresh(true);
78 
79  m_face.expressInterest(interest,
80  bind(&SegmentFetcher::afterSegmentReceived, this, _1, _2, true, self),
81  bind(&SegmentFetcher::afterNackReceived, this, _1, _2, 0, self),
82  bind(m_errorCallback, INTEREST_TIMEOUT, "Timeout"));
83 }
84 
85 void
86 SegmentFetcher::fetchNextSegment(const Interest& origInterest, const Name& dataName,
87  uint64_t segmentNo,
88  shared_ptr<SegmentFetcher> self)
89 {
90  Interest interest(origInterest); // to preserve any selectors
91  interest.refreshNonce();
92  interest.setChildSelector(0);
93  interest.setMustBeFresh(false);
94  interest.setName(dataName.getPrefix(-1).appendSegment(segmentNo));
95  m_face.expressInterest(interest,
96  bind(&SegmentFetcher::afterSegmentReceived, this, _1, _2, false, self),
97  bind(&SegmentFetcher::afterNackReceived, this, _1, _2, 0, self),
98  bind(m_errorCallback, INTEREST_TIMEOUT, "Timeout"));
99 }
100 
101 void
102 SegmentFetcher::afterSegmentReceived(const Interest& origInterest,
103  const Data& data, bool isSegmentZeroExpected,
104  shared_ptr<SegmentFetcher> self)
105 {
106  m_validator->validate(data,
107  bind(&SegmentFetcher::afterValidationSuccess, this, _1,
108  isSegmentZeroExpected, origInterest, self),
109  bind(&SegmentFetcher::afterValidationFailure, this, _1));
110 
111 }
112 
113 void
114 SegmentFetcher::afterValidationSuccess(const shared_ptr<const Data> data,
115  bool isSegmentZeroExpected,
116  const Interest& origInterest,
117  shared_ptr<SegmentFetcher> self)
118 {
119  name::Component currentSegment = data->getName().get(-1);
120 
121  if (currentSegment.isSegment()) {
122  if (isSegmentZeroExpected && currentSegment.toSegment() != 0) {
123  fetchNextSegment(origInterest, data->getName(), 0, self);
124  }
125  else {
126  m_buffer->write(reinterpret_cast<const char*>(data->getContent().value()),
127  data->getContent().value_size());
128 
129  const name::Component& finalBlockId = data->getMetaInfo().getFinalBlockId();
130  if (finalBlockId.empty() || (finalBlockId > currentSegment)) {
131  fetchNextSegment(origInterest, data->getName(), currentSegment.toSegment() + 1, self);
132  }
133  else {
134  return m_completeCallback(m_buffer->buf());
135  }
136  }
137  }
138  else {
139  m_errorCallback(DATA_HAS_NO_SEGMENT, "Data Name has no segment number.");
140  }
141 }
142 
143 void
144 SegmentFetcher::afterValidationFailure(const shared_ptr<const Data> data)
145 {
146  return m_errorCallback(SEGMENT_VALIDATION_FAIL, "Segment validation fail");
147 }
148 
149 
150 void
151 SegmentFetcher::afterNackReceived(const Interest& origInterest, const lp::Nack& nack,
152  uint32_t reExpressCount, shared_ptr<SegmentFetcher> self)
153 {
154  if (reExpressCount >= MAX_INTEREST_REEXPRESS) {
155  m_errorCallback(NACK_ERROR, "Nack Error");
156  }
157  else {
158  switch (nack.getReason()) {
160  reExpressInterest(origInterest, reExpressCount, self);
161  break;
163  m_scheduler.scheduleEvent(time::milliseconds(static_cast<uint32_t>(pow(2, reExpressCount + 1))),
164  bind(&SegmentFetcher::reExpressInterest, this,
165  origInterest, reExpressCount, self));
166  break;
167  default:
168  m_errorCallback(NACK_ERROR, "Nack Error");
169  break;
170  }
171  }
172 }
173 
174 void
175 SegmentFetcher::reExpressInterest(Interest interest, uint32_t reExpressCount,
176  shared_ptr<SegmentFetcher> self)
177 {
178  interest.refreshNonce();
179  BOOST_ASSERT(interest.hasNonce());
180 
181  m_face.expressInterest(interest,
182  bind(&SegmentFetcher::afterSegmentReceived, this, _1, _2, true, self),
183  bind(&SegmentFetcher::afterNackReceived, this, _1, _2, ++reExpressCount, self),
184  bind(m_errorCallback, INTEREST_TIMEOUT, "Timeout"));
185 }
186 
187 } // namespace util
188 } // namespace ndn
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
Definition: name.hpp:249
Copyright (c) 2011-2015 Regents of the University of California.
Interest & setMustBeFresh(bool mustBeFresh)
Definition: interest.hpp:418
function< void(uint32_t code, const std::string &msg)> ErrorCallback
void refreshNonce()
Refresh nonce.
Definition: interest.cpp:91
Utility class to fetch latest version of the segmented data.
EventId scheduleEvent(const time::nanoseconds &after, const Event &event)
Schedule one time event after the specified delay.
Definition: scheduler.cpp:85
represents an Interest packet
Definition: interest.hpp:45
function< void(const std::string &reason)> ErrorCallback
Definition: dns.hpp:79
represents a Network Nack
Definition: nack.hpp:40
NackReason getReason() const
Definition: nack.hpp:92
bool hasNonce() const
Check if Nonce set.
Definition: interest.hpp:248
const Block & get(uint32_t type) const
Get the first subelement of the requested type.
Definition: block.cpp:409
Interest & setChildSelector(int childSelector)
Definition: interest.hpp:404
Interest & setName(const Name &name)
Definition: interest.hpp:224
Name & appendSegment(uint64_t segmentNo)
Append segment number (sequential) using NDN naming conventions.
Definition: name.cpp:232
bool isSegment() const
Check if the component is segment number per NDN naming conventions.
Abstraction to communicate with local or remote NDN forwarder.
Definition: face.hpp:119
Name abstraction to represent an absolute name.
Definition: name.hpp:46
static void fetch(Face &face, const Interest &baseInterest, Validator &validator, const CompleteCallback &completeCallback, const ErrorCallback &errorCallback)
Initiate segment fetching.
Component holds a read-only name component value.
uint64_t toSegment() const
Interpret as segment number component using NDN naming conventions.
static const uint32_t MAX_INTEREST_REEXPRESS
Maximum number of times an interest will be reexpressed incase of NackCallback.
represents a Data packet
Definition: data.hpp:39
Validator is one of the main classes of the security library.
Definition: validator.hpp:46
function< void(const ConstBufferPtr &data)> CompleteCallback
const Name & getName() const
Definition: interest.hpp:218