ndn-autoconfig-server.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "core/version.hpp"
27 #include <ndn-cxx/encoding/tlv-nfd.hpp>
28 #include <ndn-cxx/face.hpp>
29 #include <ndn-cxx/security/key-chain.hpp>
30 
31 namespace ndn {
32 
33 const static Name LOCALHOP_HUB = "/localhop/ndn-autoconf/hub";
34 const static Name LOCALHOP_ROUTABLE_PREFIXES = "/localhop/nfd/rib/routable-prefixes";
35 
36 static void
37 usage(const char* programName)
38 {
39  std::cout << "Usage:\n" << programName << " [-h] [-V] [-p prefix] [-p prefix] ... Uri \n"
40  << " -h - print usage and exit\n"
41  << " -V - print version number and exit\n"
42  << " -p prefix - the local prefix of the hub\n"
43  << "\n"
44  << " Uri - a FaceMgmt URI\n"
45  << std::endl;
46 }
47 
48 class PrefixCollection : noncopyable
49 {
50 public:
51  bool
52  empty() const
53  {
54  return m_prefixes.empty();
55  }
56 
57  void
58  add(const Name& prefix)
59  {
60  m_prefixes.push_back(prefix);
61  }
62 
63  template<bool T>
64  size_t
65  wireEncode(EncodingImpl<T>& encoder) const
66  {
67  size_t totalLength = 0;
68 
69  for (std::vector<Name>::const_reverse_iterator i = m_prefixes.rbegin();
70  i != m_prefixes.rend(); ++i) {
71  totalLength += i->wireEncode(encoder);
72  }
73 
74  totalLength += encoder.prependVarNumber(totalLength);
75  totalLength += encoder.prependVarNumber(tlv::Content);
76  return totalLength;
77  }
78 
79  Block
80  wireEncode() const
81  {
82  Block block;
83 
84  EncodingEstimator estimator;
85  size_t estimatedSize = wireEncode(estimator);
86 
87  EncodingBuffer buffer(estimatedSize);
88  wireEncode(buffer);
89 
90  return buffer.block();
91  }
92 
93 private:
94  std::vector<Name> m_prefixes;
95 };
96 
97 class NdnAutoconfigServer : noncopyable
98 {
99 public:
100  NdnAutoconfigServer(const std::string& hubFaceUri, const PrefixCollection& routablePrefixes)
101  {
102  KeyChain m_keyChain;
103 
104  // pre-create hub Data
105  m_hubData = make_shared<Data>(Name(LOCALHOP_HUB).appendVersion());
106  m_hubData->setFreshnessPeriod(time::hours(1)); // 1 hour
107  m_hubData->setContent(makeBinaryBlock(tlv::nfd::Uri,
108  reinterpret_cast<const uint8_t*>(hubFaceUri.c_str()),
109  hubFaceUri.size()));
110  m_keyChain.sign(*m_hubData);
111 
112  // pre-create routable prefix Data
113  if (!routablePrefixes.empty()) {
114  Name routablePrefixesDataName(LOCALHOP_ROUTABLE_PREFIXES);
115  routablePrefixesDataName.appendVersion();
116  routablePrefixesDataName.appendSegment(0);
117  m_routablePrefixesData = make_shared<Data>(routablePrefixesDataName);
118  m_routablePrefixesData->setContent(routablePrefixes.wireEncode());
119  m_routablePrefixesData->setFinalBlockId(routablePrefixesDataName.get(-1));
120  m_routablePrefixesData->setFreshnessPeriod(time::seconds(5)); // 5s
121  m_keyChain.sign(*m_routablePrefixesData);
122  }
123  }
124 
125  void
126  onHubInterest(const Name& name, const Interest& interest)
127  {
128  m_face.put(*m_hubData);
129  }
130 
131  void
132  onRoutablePrefixesInterest(const Name& name, const Interest& interest)
133  {
134  m_face.put(*m_routablePrefixesData);
135  }
136 
137  void
138  onRegisterFailed(const Name& prefix, const std::string& reason)
139  {
140  std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" <<
141  reason << ")" << std::endl;
142  m_face.shutdown();
143  }
144 
145  void
146  run()
147  {
148  m_face.setInterestFilter(LOCALHOP_HUB,
149  bind(&NdnAutoconfigServer::onHubInterest, this, _1, _2),
150  RegisterPrefixSuccessCallback(),
151  bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
152 
153  if (static_cast<bool>(m_routablePrefixesData)) {
154  m_face.setInterestFilter(LOCALHOP_ROUTABLE_PREFIXES,
155  bind(&NdnAutoconfigServer::onRoutablePrefixesInterest, this, _1, _2),
156  RegisterPrefixSuccessCallback(),
157  bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
158  }
159 
160  m_face.processEvents();
161  }
162 
163 private:
164  Face m_face;
165 
166  shared_ptr<Data> m_hubData;
167  shared_ptr<Data> m_routablePrefixesData;
168 };
169 
170 int
171 main(int argc, char** argv)
172 {
173  const char* programName = argv[0];
174 
175  PrefixCollection routablePrefixes;
176 
177  int opt;
178  while ((opt = getopt(argc, argv, "hVp:")) != -1) {
179  switch (opt) {
180  case 'h':
181  usage(programName);
182  return 0;
183  case 'V':
184  std::cout << NFD_VERSION_BUILD_STRING << std::endl;
185  return 0;
186  case 'p':
187  routablePrefixes.add(Name(optarg));
188  break;
189  default:
190  usage(programName);
191  return 1;
192  }
193  }
194 
195  if (argc != optind + 1) {
196  usage(programName);
197  return 1;
198  }
199 
200  std::string hubFaceUri = argv[optind];
201  NdnAutoconfigServer instance(hubFaceUri, routablePrefixes);
202 
203  try {
204  instance.run();
205  }
206  catch (const std::exception& error) {
207  std::cerr << "ERROR: " << error.what() << std::endl;
208  return 1;
209  }
210  return 0;
211 }
212 
213 } // namespace ndn
214 
215 int
216 main(int argc, char** argv)
217 {
218  return ndn::main(argc, argv);
219 }
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
Definition: nfd.hpp:35
static void usage(const char *programName)
int main(int argc, char **argv)
static const Name LOCALHOP_ROUTABLE_PREFIXES
int main(int argc, char **argv)
static const Name LOCALHOP_HUB