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