blob: 0630fa44eac77fde3e2dd5180d0b5d9344a8c47f [file] [log] [blame]
Alexander Afanasyev93338872017-01-30 22:37:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0f830802018-01-16 23:58:58 -05002/*
3 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyev93338872017-01-30 22:37:00 -08004 *
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
22#ifndef NDN_SECURITY_V2_VALIDATION_POLICY_COMMAND_INTEREST_HPP
23#define NDN_SECURITY_V2_VALIDATION_POLICY_COMMAND_INTEREST_HPP
24
25#include "validation-policy.hpp"
Davide Pesavento5df42a82018-03-08 20:06:51 -050026
Alexander Afanasyev93338872017-01-30 22:37:00 -080027#include <boost/multi_index_container.hpp>
28#include <boost/multi_index/ordered_index.hpp>
29#include <boost/multi_index/sequenced_index.hpp>
30#include <boost/multi_index/key_extractors.hpp>
31
32namespace ndn {
33namespace security {
34namespace v2 {
35
36/** \brief Validation policy for stop-and-wait command Interests
37 * \sa https://redmine.named-data.net/projects/ndn-cxx/wiki/CommandInterest
38 *
39 * This policy checks the timestamp field of a stop-and-wait command Interest.
40 * Signed Interest validation and Data validation requests are delegated to an inner policy.
41 */
42class ValidationPolicyCommandInterest : public ValidationPolicy
43{
44public:
45 class Options
46 {
47 public:
48 Options()
49 {
50 }
51
52 public:
53 /** \brief tolerance of initial timestamp
54 *
55 * A stop-and-wait command Interest is considered "initial" if the validator
56 * has not recorded the last timestamp from the same public key, or when
57 * such knowledge has been erased.
58 * For an initial command Interest, its timestamp is compared to the current
59 * system clock, and the command Interest is rejected if the absolute difference
60 * is greater than the grace interval.
61 *
62 * This should be positive.
63 * Setting this option to 0 or negative causes the validator to require exactly same
64 * timestamp as the system clock, which most likely rejects all command Interests.
65 */
Davide Pesavento0f830802018-01-16 23:58:58 -050066 time::nanoseconds gracePeriod = 2_min;
Alexander Afanasyev93338872017-01-30 22:37:00 -080067
68 /** \brief max number of distinct public keys of which to record the last timestamp
69 *
70 * The validator records last timestamps for every public key.
71 * For a subsequent command Interest using the same public key,
72 * its timestamp is compared to the last timestamp from that public key,
73 * and the command Interest is rejected if its timestamp is
74 * less than or equal to the recorded timestamp.
75 *
76 * This option limits the number of distinct public keys being tracked.
77 * If the limit is exceeded, the oldest record is deleted.
78 *
79 * Setting this option to -1 allows tracking unlimited public keys.
80 * Setting this option to 0 disables last timestamp records and causes
81 * every command Interest to be processed as initial.
82 */
83 ssize_t maxRecords = 1000;
84
85 /** \brief max lifetime of a last timestamp record
86 *
87 * A last timestamp record expires and can be deleted if it has not been refreshed
88 * within this duration.
89 * Setting this option to 0 or negative makes last timestamp records expire immediately
90 * and causes every command Interest to be processed as initial.
91 */
Davide Pesavento0f830802018-01-16 23:58:58 -050092 time::nanoseconds recordLifetime = 1_h;
Alexander Afanasyev93338872017-01-30 22:37:00 -080093 };
94
95 /** \brief constructor
96 * \param inner a Validator for signed Interest signature validation and Data validation;
97 * this must not be nullptr
98 * \param options stop-and-wait command Interest validation options
99 * \throw std::invalid_argument inner policy is nullptr
100 */
101 explicit
102 ValidationPolicyCommandInterest(unique_ptr<ValidationPolicy> inner,
103 const Options& options = {});
104
105protected:
106 void
107 checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
108 const ValidationContinuation& continueValidation) override;
109
110 void
111 checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
112 const ValidationContinuation& continueValidation) override;
113
114private:
115 void
116 cleanup();
117
118 std::tuple<bool, Name, uint64_t>
119 parseCommandInterest(const Interest& interest, const shared_ptr<ValidationState>& state) const;
120
121 bool
122 checkTimestamp(const shared_ptr<ValidationState>& state,
123 const Name& keyName, uint64_t timestamp);
124
125 void
Davide Pesavento5df42a82018-03-08 20:06:51 -0500126 insertNewRecord(const Name& keyName, uint64_t timestamp);
Alexander Afanasyev93338872017-01-30 22:37:00 -0800127
128private:
Alexander Afanasyev93338872017-01-30 22:37:00 -0800129 Options m_options;
130
131 struct LastTimestampRecord
132 {
133 Name keyName;
134 uint64_t timestamp;
135 time::steady_clock::TimePoint lastRefreshed;
136 };
137
Davide Pesavento5df42a82018-03-08 20:06:51 -0500138 using Container = boost::multi_index_container<
Alexander Afanasyev93338872017-01-30 22:37:00 -0800139 LastTimestampRecord,
140 boost::multi_index::indexed_by<
141 boost::multi_index::ordered_unique<
142 boost::multi_index::member<LastTimestampRecord, Name, &LastTimestampRecord::keyName>
143 >,
144 boost::multi_index::sequenced<>
145 >
Davide Pesavento5df42a82018-03-08 20:06:51 -0500146 >;
147 using Index = Container::nth_index<0>::type;
148 using Queue = Container::nth_index<1>::type;
Alexander Afanasyev93338872017-01-30 22:37:00 -0800149
150 Container m_container;
151 Index& m_index;
152 Queue& m_queue;
153};
154
155} // namespace v2
156} // namespace security
157} // namespace ndn
158
Alexander Afanasyev93338872017-01-30 22:37:00 -0800159#endif // NDN_SECURITY_V2_VALIDATION_POLICY_COMMAND_INTEREST_HPP