NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
validation-policy-command-interest.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
23 
24 namespace ndn {
25 namespace security {
26 namespace v2 {
27 
29  const Options& options)
30  : m_options(options)
31  , m_index(m_container.get<0>())
32  , m_queue(m_container.get<1>())
33 {
34  if (inner == nullptr) {
35  NDN_THROW(std::invalid_argument("inner policy is missing"));
36  }
37  setInnerPolicy(std::move(inner));
38 
39  m_options.gracePeriod = std::max(m_options.gracePeriod, 0_ns);
40 }
41 
42 void
43 ValidationPolicyCommandInterest::checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
44  const ValidationContinuation& continueValidation)
45 {
46  getInnerPolicy().checkPolicy(data, state, continueValidation);
47 }
48 
49 void
50 ValidationPolicyCommandInterest::checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
51  const ValidationContinuation& continueValidation)
52 {
53  bool isOk = false;
54  Name keyName;
55  uint64_t timestamp = 0;
56  std::tie(isOk, keyName, timestamp) = parseCommandInterest(interest, state);
57  if (!isOk) {
58  return;
59  }
60 
61  if (!checkTimestamp(state, keyName, timestamp)) {
62  return;
63  }
64  getInnerPolicy().checkPolicy(interest, state, std::bind(continueValidation, _1, _2));
65 }
66 
67 void
68 ValidationPolicyCommandInterest::cleanup()
69 {
70  auto expiring = time::steady_clock::now() - m_options.recordLifetime;
71 
72  while ((!m_queue.empty() && m_queue.front().lastRefreshed <= expiring) ||
73  (m_options.maxRecords >= 0 &&
74  m_queue.size() > static_cast<size_t>(m_options.maxRecords))) {
75  m_queue.pop_front();
76  }
77 }
78 
79 std::tuple<bool, Name, uint64_t>
80 ValidationPolicyCommandInterest::parseCommandInterest(const Interest& interest,
81  const shared_ptr<ValidationState>& state) const
82 {
83  const Name& name = interest.getName();
84  if (name.size() < command_interest::MIN_SIZE) {
85  state->fail({ValidationError::POLICY_ERROR, "Command interest name `" +
86  interest.getName().toUri() + "` is too short"});
87  return std::make_tuple(false, Name(), 0);
88  }
89 
90  const name::Component& timestampComp = name.at(command_interest::POS_TIMESTAMP);
91  if (!timestampComp.isNumber()) {
92  state->fail({ValidationError::POLICY_ERROR, "Command interest `" +
93  interest.getName().toUri() + "` doesn't include timestamp component"});
94  return std::make_tuple(false, Name(), 0);
95  }
96 
97  Name klName = getKeyLocatorName(interest, *state);
98  if (!state->getOutcome()) { // already failed
99  return std::make_tuple(false, Name(), 0);
100  }
101 
102  return std::make_tuple(true, klName, timestampComp.toNumber());
103 }
104 
105 bool
106 ValidationPolicyCommandInterest::checkTimestamp(const shared_ptr<ValidationState>& state,
107  const Name& keyName, uint64_t timestamp)
108 {
109  this->cleanup();
110 
111  auto now = time::system_clock::now();
112  auto timestampPoint = time::fromUnixTimestamp(time::milliseconds(timestamp));
113  if (timestampPoint < now - m_options.gracePeriod || timestampPoint > now + m_options.gracePeriod) {
114  state->fail({ValidationError::POLICY_ERROR,
115  "Timestamp is outside the grace period for key " + keyName.toUri()});
116  return false;
117  }
118 
119  auto it = m_index.find(keyName);
120  if (it != m_index.end()) {
121  if (timestamp <= it->timestamp) {
122  state->fail({ValidationError::POLICY_ERROR,
123  "Timestamp is reordered for key " + keyName.toUri()});
124  return false;
125  }
126  }
127 
128  auto interestState = dynamic_pointer_cast<InterestValidationState>(state);
129  BOOST_ASSERT(interestState != nullptr);
130  interestState->afterSuccess.connect([=] (const Interest&) { insertNewRecord(keyName, timestamp); });
131  return true;
132 }
133 
134 void
135 ValidationPolicyCommandInterest::insertNewRecord(const Name& keyName, uint64_t timestamp)
136 {
137  // try to insert new record
138  auto now = time::steady_clock::now();
139  auto i = m_queue.end();
140  bool isNew = false;
141  LastTimestampRecord newRecord{keyName, timestamp, now};
142  std::tie(i, isNew) = m_queue.push_back(newRecord);
143 
144  if (!isNew) {
145  BOOST_ASSERT(i->keyName == keyName);
146 
147  // set lastRefreshed field, and move to queue tail
148  m_queue.erase(i);
149  isNew = m_queue.push_back(newRecord).second;
150  BOOST_VERIFY(isNew);
151  }
152 }
153 
154 } // namespace v2
155 } // namespace security
156 } // namespace ndn
ndn::name::Component::isNumber
bool isNumber() const
Check if the component is a nonNegativeInteger.
Definition: name-component.cpp:204
ndn::security::v2::ValidationPolicyCommandInterest::Options::recordLifetime
time::nanoseconds recordLifetime
max lifetime of a last timestamp record
Definition: validation-policy-command-interest.hpp:92
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
ndn::security::v2::ValidationPolicyCommandInterest::ValidationPolicyCommandInterest
ValidationPolicyCommandInterest(unique_ptr< ValidationPolicy > inner, const Options &options={})
constructor
Definition: validation-policy-command-interest.cpp:28
ndn::tlv::Interest
@ Interest
Definition: tlv.hpp:65
nonstd::variants::get
R & get(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &v, nonstd_lite_in_place_type_t(R)=nonstd_lite_in_place_type(R))
Definition: variant.hpp:1753
ndn::time::steady_clock::now
static time_point now() noexcept
Definition: time.cpp:80
validation-policy-command-interest.hpp
ndn::time::system_clock::now
static time_point now() noexcept
Definition: time.cpp:46
ndn::security::v2::ValidationError::POLICY_ERROR
@ POLICY_ERROR
Definition: validation-error.hpp:51
ndn::security::v2::ValidationPolicyCommandInterest::checkPolicy
void checkPolicy(const Data &data, const shared_ptr< ValidationState > &state, const ValidationContinuation &continueValidation) override
Check data against the policy.
Definition: validation-policy-command-interest.cpp:43
ndn::security::v2::ValidationPolicy::ValidationContinuation
std::function< void(const shared_ptr< CertificateRequest > &certRequest, const shared_ptr< ValidationState > &state)> ValidationContinuation
Definition: validation-policy.hpp:41
ndn::name::Component::toNumber
uint64_t toNumber() const
Interpret this name component as nonNegativeInteger.
Definition: name-component.cpp:255
ndn::security::v2::ValidationPolicyCommandInterest::Options::maxRecords
ssize_t maxRecords
max number of distinct public keys of which to record the last timestamp
Definition: validation-policy-command-interest.hpp:83
ndn::Name
Represents an absolute name.
Definition: name.hpp:44
ndn::security::v2::ValidationPolicy::setInnerPolicy
void setInnerPolicy(unique_ptr< ValidationPolicy > innerPolicy)
Set inner policy.
Definition: validation-policy.cpp:30
ns3::ndn::Name
Name
Definition: ndn-common.cpp:25
ndn::security::v2::ValidationPolicyCommandInterest::Options::gracePeriod
time::nanoseconds gracePeriod
tolerance of initial timestamp
Definition: validation-policy-command-interest.hpp:66
ndn::security::v2::ValidationPolicy::checkPolicy
virtual void checkPolicy(const Data &data, const shared_ptr< ValidationState > &state, const ValidationContinuation &continueValidation)=0
Check data against the policy.
NDN_THROW
#define NDN_THROW(e)
Definition: exception.hpp:61
ndn::command_interest::POS_TIMESTAMP
const ssize_t POS_TIMESTAMP
Definition: security-common.hpp:46
ndn::command_interest::MIN_SIZE
const size_t MIN_SIZE
minimal number of components for Command Interest
Definition: security-common.hpp:51
ndn::time::fromUnixTimestamp
system_clock::TimePoint fromUnixTimestamp(milliseconds duration)
Convert UNIX timestamp to system_clock::TimePoint.
Definition: time.cpp:119
ndn::Interest
Represents an Interest packet.
Definition: interest.hpp:44
ndn::Data
Represents a Data packet.
Definition: data.hpp:36
ndn::name::Component
Represents a name component.
Definition: name-component.hpp:94
ndn::security::v2::ValidationPolicyCommandInterest::Options
Definition: validation-policy-command-interest.hpp:46
ndn::name
Definition: name-component-types.hpp:33
ndn::Interest::getName
const Name & getName() const noexcept
Definition: interest.hpp:121
ndn::security::v2::getKeyLocatorName
static Name getKeyLocatorName(const SignatureInfo &si, ValidationState &state)
Definition: validation-policy.cpp:64
ndn::security::v2::ValidationPolicy::getInnerPolicy
ValidationPolicy & getInnerPolicy()
Return the inner policy.
Definition: validation-policy.cpp:49
ndn
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-strategy-choice-helper.hpp:34