NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
command-interest-validator.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
24 #include <boost/lexical_cast.hpp>
25 
26 namespace ndn {
27 namespace security {
28 
29 std::ostream&
31 {
32  switch (error) {
34  return os << "OK";
36  return os << "command Interest name is too short";
38  return os << "cannot parse timestamp";
40  return os << "cannot parse SignatureInfo";
42  return os << "KeyLocator is missing";
44  return os << "KeyLocator type is not Name";
46  return os << "cannot parse certificate name";
48  return os << "timestamp is out of grace period";
50  return os << "timestamp is less than or equal to last timestamp";
51  }
52  return os;
53 }
54 
55 static void
56 invokeReject(const OnInterestValidationFailed& reject, const Interest& interest,
58 {
59  reject(interest.shared_from_this(), boost::lexical_cast<std::string>(error));
60 }
61 
63  const Options& options)
64  : m_inner(std::move(inner))
65  , m_options(options)
66  , m_index(m_container.get<0>())
67  , m_queue(m_container.get<1>())
68 {
69  if (m_inner == nullptr) {
70  BOOST_THROW_EXCEPTION(std::invalid_argument("inner validator is nullptr"));
71  }
72 
73  m_options.gracePeriod = std::max(m_options.gracePeriod, time::nanoseconds::zero());
74 }
75 
76 void
77 CommandInterestValidator::checkPolicy(const Interest& interest, int nSteps,
78  const OnInterestValidated& accept,
79  const OnInterestValidationFailed& reject,
80  std::vector<shared_ptr<ValidationRequest>>& nextSteps)
81 {
82  BOOST_ASSERT(nSteps == 0);
83  this->cleanup();
84 
85  Name keyName;
86  uint64_t timestamp;
87  ErrorCode res = this->parseCommandInterest(interest, keyName, timestamp);
88  if (res != ErrorCode::NONE) {
89  return invokeReject(reject, interest, res);
90  }
91 
93 
94  m_inner->validate(interest,
95  [=] (const shared_ptr<const Interest>& interest) {
96  ErrorCode res = this->checkTimestamp(keyName, timestamp, receiveTime);
97  if (res != ErrorCode::NONE) {
98  return invokeReject(reject, *interest, res);
99  }
100  accept(interest);
101  }, reject);
102 }
103 
104 void
105 CommandInterestValidator::cleanup()
106 {
108 
109  while ((!m_queue.empty() && m_queue.front().lastRefreshed <= expiring) ||
110  (m_options.maxTimestamps >= 0 &&
111  m_queue.size() > static_cast<size_t>(m_options.maxTimestamps))) {
112  m_queue.pop_front();
113  }
114 }
115 
117 CommandInterestValidator::parseCommandInterest(const Interest& interest, Name& keyName,
118  uint64_t& timestamp) const
119 {
120  const Name& name = interest.getName();
121  if (name.size() < signed_interest::MIN_LENGTH) {
123  }
124 
125  const name::Component& timestampComp = name[signed_interest::POS_TIMESTAMP];
126  if (!timestampComp.isNumber()) {
128  }
129  timestamp = timestampComp.toNumber();
130 
131  SignatureInfo sig;
132  try {
133  sig.wireDecode(name[signed_interest::POS_SIG_INFO].blockFromValue());
134  }
135  catch (const tlv::Error&) {
137  }
138 
139  if (!sig.hasKeyLocator()) {
141  }
142 
143  const KeyLocator& keyLocator = sig.getKeyLocator();
144  if (keyLocator.getType() != KeyLocator::KeyLocator_Name) {
146  }
147 
148  try {
150  }
151  catch (const v1::IdentityCertificate::Error&) {
153  }
154 
155  return ErrorCode::NONE;
156 }
157 
159 CommandInterestValidator::checkTimestamp(const Name& keyName, uint64_t timestamp,
160  time::system_clock::TimePoint receiveTime)
161 {
163 
164  // try to insert new record
165  Queue::iterator i = m_queue.end();
166  bool isNew = false;
167  std::tie(i, isNew) = m_queue.push_back({keyName, timestamp, now});
168 
169  if (isNew) {
170  // check grace period
171  time::system_clock::TimePoint sigTime = time::fromUnixTimestamp(time::milliseconds(timestamp));
172  if (time::abs(sigTime - receiveTime) > m_options.gracePeriod) {
173  // out of grace period, delete new record
174  m_queue.erase(i);
176  }
177  }
178  else {
179  BOOST_ASSERT(i->keyName == keyName);
180 
181  // compare timestamp with last timestamp
182  if (timestamp <= i->timestamp) {
184  }
185 
186  // set lastRefreshed field, and move to queue tail
187  m_queue.erase(i);
188  isNew = m_queue.push_back({keyName, timestamp, now}).second;
189  BOOST_ASSERT(isNew);
190  }
191 
192  return ErrorCode::NONE;
193 }
194 
195 void
197  const OnDataValidated& accept,
198  const OnDataValidationFailed& reject,
199  std::vector<shared_ptr<ValidationRequest>>& nextSteps)
200 {
201  BOOST_ASSERT(nSteps == 0);
202  m_inner->validate(data, accept, reject);
203 }
204 
205 } // namespace security
206 } // namespace ndn
function< void(const shared_ptr< const Interest > &, const std::string &)> OnInterestValidationFailed
Callback to report a failed Interest validation.
time_point TimePoint
Definition: time.hpp:120
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
Copyright (c) 2011-2015 Regents of the University of California.
const KeyLocator & getKeyLocator() const
Get KeyLocator.
static time_point now() noexcept
Definition: time.cpp:79
time::nanoseconds timestampTtl
max lifetime of a last timestamp record
const Name & getName() const
get Name element
STL namespace.
represents an Interest packet
Definition: interest.hpp:42
const ssize_t POS_TIMESTAMP
indicates KeyLocator contains a Name
Definition: key-locator.hpp:49
static time_point now() noexcept
Definition: time.cpp:45
function< void(const shared_ptr< const Data > &, const std::string &)> OnDataValidationFailed
Callback to report a failed Data validation.
std::ostream & operator<<(std::ostream &os, CommandInterestValidator::ErrorCode error)
constexpr duration< Rep, Period > abs(duration< Rep, Period > d)
Definition: time.hpp:53
function< void(const shared_ptr< const Data > &)> OnDataValidated
Callback to report a successful Data validation.
bool isNumber() const
Check if the component is nonNegativeInteger.
Table::const_iterator iterator
Definition: cs-internal.hpp:41
function< void(const shared_ptr< const Interest > &)> OnInterestValidated
Callback to report a successful Interest validation.
const size_t MIN_LENGTH
minimal number of components for Command Interest
bool hasKeyLocator() const
Check if KeyLocator is set.
CommandInterestValidator(unique_ptr< Validator > inner, const Options &options=Options())
constructor
static void invokeReject(const OnInterestValidationFailed &reject, const Interest &interest, CommandInterestValidator::ErrorCode error)
virtual void checkPolicy(const Interest &interest, int nSteps, const OnInterestValidated &accept, const OnInterestValidationFailed &reject, std::vector< shared_ptr< ValidationRequest >> &nextSteps) override
validate command Interest
time::nanoseconds gracePeriod
tolerance of initial timestamp
Name abstraction to represent an absolute name.
Definition: name.hpp:46
size_t size() const
Get the number of components.
Definition: name.hpp:400
uint64_t toNumber() const
Interpret this name component as nonNegativeInteger.
time_point TimePoint
Definition: time.hpp:90
Component holds a read-only name component value.
void wireDecode(const Block &wire)
Decode from a wire format.
system_clock::TimePoint fromUnixTimestamp(const milliseconds &duration)
Convert UNIX timestamp to system_clock::TimePoint.
Definition: time.cpp:124
const ssize_t POS_SIG_INFO
Type getType() const
ssize_t maxTimestamps
max number of distinct public keys to record last timestamp
represents a Data packet
Definition: data.hpp:37
represents an error in TLV encoding or decoding
Definition: tlv.hpp:50
const Name & getName() const
Definition: interest.hpp:215