esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rdr.hpp
Go to the documentation of this file.
1 #ifndef NDNPH_APP_RDR_HPP
2 #define NDNPH_APP_RDR_HPP
3 
4 #include "../face/packet-handler.hpp"
5 #include "../keychain/digest.hpp"
6 #include "../keychain/null.hpp"
7 
8 namespace ndnph {
9 namespace rdr {
10 
12 inline Component
14  static const uint8_t tlv[]{0x20, 0x08, 'm', 'e', 't', 'a', 'd', 'a', 't', 'a'};
15  static Component comp = Component::constant(tlv, sizeof(tlv));
16  return comp;
17 }
18 
23 inline Name
25  if (!data) {
26  return Name();
27  }
28 
29  Name datasetPrefix;
30  bool ok = data.getContent().makeDecoder().decode(datasetPrefix);
31  if (!ok) {
32  return Name();
33  }
34  return datasetPrefix;
35 }
36 
37 namespace detail {
38 
39 inline Name
41  return rdrPrefix[-1] == getMetadataComponent() ? rdrPrefix.getPrefix(-1) : rdrPrefix;
42 }
43 
44 } // namespace detail
45 
55 public:
56  struct Options {
62  uint64_t initialVersion;
63 
69  uint32_t freshnessPeriod;
70 
73  };
74 
81  explicit RdrMetadataProducer(const Name& rdrPrefix, Face& face, const Options& opts)
82  : PacketHandler(face)
83  , m_rdrPrefix(detail::stripMetadataComponent(rdrPrefix))
84  , m_signer(opts.signer)
85  , m_version(opts.initialVersion)
86  , m_freshness(std::max<uint32_t>(opts.freshnessPeriod, 1)) {
87  if (m_version + 1 == 0) {
88  port::RandomSource::generate(reinterpret_cast<uint8_t*>(&m_version), sizeof(m_version));
89  m_version = m_version & ~0xFFFFFFFF;
90  }
91  }
92 
93  explicit RdrMetadataProducer(const Name& rdrPrefix, Face& face)
94  : RdrMetadataProducer(rdrPrefix, face,
95  Options{
96  .initialVersion = std::numeric_limits<uint64_t>::max(),
97  .freshnessPeriod = 1,
98  .signer = DigestKey::get(),
99  }) {}
100 
105  void setDatasetPrefix(Name datasetPrefix) {
106  m_datasetPrefix = datasetPrefix;
107  ++m_version;
108  }
109 
110 private:
111  bool processInterest(Interest interest) final {
112  const Name& interestName = interest.getName();
113  if (!m_datasetPrefix || interestName.getPrefix(-1) != m_rdrPrefix ||
114  interestName[-1] != getMetadataComponent() || !interest.getCanBePrefix() ||
115  !interest.getMustBeFresh()) {
116  return false;
117  }
118 
119  StaticRegion<1024> region;
120  Data data = region.create<Data>();
121  NDNPH_ASSERT(!!data);
122  data.setName(m_rdrPrefix.append(region, getMetadataComponent(), convention::Version(),
123  m_version, convention::Segment(), 0));
124  data.setFreshnessPeriod(m_freshness);
125  data.setIsFinalBlock(true);
126 
127  Encoder contentEncoder(region);
128  prepareRdrContent(contentEncoder, m_datasetPrefix);
129  contentEncoder.trim();
130  data.setContent(tlv::Value(contentEncoder));
131 
132  reply(data.sign(m_signer));
133  return true;
134  }
135 
141  virtual void prepareRdrContent(Encoder& encoder, const Name& datasetPrefix) {
142  encoder.prepend(datasetPrefix);
143  }
144 
145 private:
146  Name m_rdrPrefix;
147  const PrivateKey& m_signer;
148  uint64_t m_version = 0;
149  uint32_t m_freshness = 1;
150  Name m_datasetPrefix;
151 };
152 
158 public:
159  using Callback = void (*)(void* ctx, Data data);
160 
161  struct Options {
164  };
165 
166  explicit RdrMetadataConsumer(Face& face, const Options& opts)
167  : PacketHandler(face, 0x60)
168  , m_pending(this)
169  , m_verifier(opts.verifier)
170  , m_interestLifetime(opts.interestLifetime) {}
171 
172  explicit RdrMetadataConsumer(Face& face)
174  .verifier = NullKey::get(),
175  .interestLifetime = 1000,
176  }) {}
177 
178  void start(Name rdrPrefix, Callback cb, void* ctx = nullptr) {
179  invokeCallback(Data());
180 
181  m_rdrPrefix = detail::stripMetadataComponent(rdrPrefix);
182  m_cb = cb;
183  m_ctx = ctx;
184 
185  StaticRegion<1024> region;
186  auto interest = region.create<Interest>();
187  NDNPH_ASSERT(!!interest);
188  interest.setName(m_rdrPrefix.append(region, getMetadataComponent()));
189  interest.setCanBePrefix(true);
190  interest.setMustBeFresh(true);
191  interest.setLifetime(m_interestLifetime);
192  bool ok = m_pending.send(interest);
193  if (!ok) {
194  invokeCallback(Data());
195  }
196  }
197 
198 private:
199  void invokeCallback(Data data) {
200  if (m_cb != nullptr) {
201  m_cb(m_ctx, std::move(data));
202  m_cb = nullptr;
203  }
204  }
205 
206  void loop() final {
207  if (m_pending.expired()) {
208  invokeCallback(Data());
209  }
210  }
211 
212  bool processData(Data data) final {
213  if (!m_pending.match(data, m_rdrPrefix) || data.getName().size() != m_rdrPrefix.size() + 3 ||
214  data.getName()[m_rdrPrefix.size()] != getMetadataComponent()) {
215  return false;
216  }
217 
218  if (!data.verify(m_verifier)) {
219  invokeCallback(Data());
220  } else {
221  invokeCallback(data);
222  }
223  return true;
224  }
225 
226 private:
227  OutgoingPendingInterest m_pending;
228  const PublicKey& m_verifier;
229  uint16_t m_interestLifetime = 0;
230  Name m_rdrPrefix;
231  Callback m_cb = nullptr;
232  void* m_ctx = nullptr;
233 };
234 
235 } // namespace rdr
236 
237 using rdr::RdrMetadataConsumer;
238 using rdr::RdrMetadataProducer;
239 
240 } // namespace ndnph
241 
242 #endif // NDNPH_APP_RDR_HPP
static bool generate(uint8_t *output, size_t count)
Name component.
Definition: component.hpp:16
static Component constant(const uint8_t *tlv, size_t size)
Construct from const TLV buffer.
Definition: component.hpp:64
Data packet.
Definition: data.hpp:136
void setContent(tlv::Value v)
Definition: data.hpp:176
void setName(const Name &v)
Definition: data.hpp:144
tlv::Value getContent() const
Definition: data.hpp:172
const Name & getName() const
Definition: data.hpp:140
Signed sign(const PrivateKey &key, DSigInfo sigInfo=DSigInfo()) const
Sign the packet with a private key.
Definition: data.hpp:254
void setFreshnessPeriod(uint32_t v)
Definition: data.hpp:160
void setIsFinalBlock(bool v)
Definition: data.hpp:168
bool verify(const PublicKey &key) const
Verify the packet with a public key.
Definition: data.hpp:263
bool decode(T &target) const
Decode first TLV into target object.
Definition: decoder.hpp:158
DigestSha256 signing and verification.
Definition: digest.hpp:14
TLV encoder that accepts items in reverse order.
Definition: encoder.hpp:10
bool prepend(const First &first, const Arg &... arg)
Prepend a sequence of values.
Definition: encoder.hpp:123
Network layer face.
Definition: face.hpp:12
Interest packet.
Definition: interest.hpp:284
Name.
Definition: name.hpp:14
size_t size() const
Get number of components.
Definition: name.hpp:86
Name append(Region &region, const C &... comps) const
Append a sequence of components.
Definition: name.hpp:183
Name getPrefix(int n=0) const
Get prefix of n components.
Definition: name.hpp:165
Null signature: packet is not signed.
Definition: null.hpp:20
bool expired() const
Determine if the pending Interest has expired / timed out.
Definition: packet-handler.hpp:208
bool match(const Data &data, const Interest &interest) const
Check Interest-Data match.
Definition: packet-handler.hpp:182
bool send(const Packet &interest, int timeout, Arg &&... arg)
Send an Interest.
Definition: packet-handler.hpp:141
Base class to receive packets from Face.
Definition: packet-handler.hpp:10
bool reply(Arg &&... arg)
Synchronously transmit a packet in reply to current processing packet.
Definition: packet-handler.hpp:119
Private key.
Definition: private-key.hpp:9
Public key.
Definition: public-key.hpp:9
RefType create(Arg &&... arg)
Allocate and create an object, and return its reference.
Definition: region.hpp:90
Region with statically allocated memory.
Definition: region.hpp:143
Definition: convention.hpp:111
Consumer of RDR metadata packet.
Definition: rdr.hpp:157
RdrMetadataConsumer(Face &face)
Definition: rdr.hpp:172
void(*)(void *ctx, Data data) Callback
Definition: rdr.hpp:159
void start(Name rdrPrefix, Callback cb, void *ctx=nullptr)
Definition: rdr.hpp:178
RdrMetadataConsumer(Face &face, const Options &opts)
Definition: rdr.hpp:166
Producer of RDR metadata packet.
Definition: rdr.hpp:54
void setDatasetPrefix(Name datasetPrefix)
Set the dataset prefix.
Definition: rdr.hpp:105
RdrMetadataProducer(const Name &rdrPrefix, Face &face)
Definition: rdr.hpp:93
RdrMetadataProducer(const Name &rdrPrefix, Face &face, const Options &opts)
Constructor.
Definition: rdr.hpp:81
virtual void prepareRdrContent(Encoder &encoder, const Name &datasetPrefix)
Prepare Content of RDR metadata packet.
Definition: rdr.hpp:141
A sequence of bytes, usually TLV-VALUE.
Definition: value.hpp:11
Decoder makeDecoder() const
Create a Decoder over this value buffer.
Definition: value.hpp:64
#define NDNPH_ASSERT(x)
Definition: common.hpp:30
@ Name
Definition: an.hpp:19
@ Data
Definition: an.hpp:41
Name stripMetadataComponent(Name rdrPrefix)
Definition: rdr.hpp:40
Component getMetadataComponent()
Return '32=metadata' component.
Definition: rdr.hpp:13
Name parseMetadata(Data data)
Parse RDR metadata packet.
Definition: rdr.hpp:24
Definition: fs.hpp:33
uint16_t interestLifetime
Definition: rdr.hpp:163
const PublicKey & verifier
Definition: rdr.hpp:162
const PrivateKey & signer
Data packet signer.
Definition: rdr.hpp:72
uint64_t initialVersion
Initial version number.
Definition: rdr.hpp:62
uint32_t freshnessPeriod
Data FreshnessPeriod.
Definition: rdr.hpp:69