blob: 84bcf748c8069a6d8591c5a5abe4c1ae83b3fed5 [file] [log] [blame]
hilatadd50ada2014-03-13 12:48:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi51493202016-07-23 02:03:08 +00003 * Copyright (c) 2014-2016, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Junxiao Shi51493202016-07-23 02:03:08 +000024 */
hilatadd50ada2014-03-13 12:48:47 -050025
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070026#include "version.hpp"
Junxiao Shi0de23a22015-12-03 20:07:02 +000027#include <ndn-cxx/encoding/tlv-nfd.hpp>
Alexander Afanasyev4a771362014-04-24 21:29:33 -070028#include <ndn-cxx/face.hpp>
29#include <ndn-cxx/security/key-chain.hpp>
hilatadd50ada2014-03-13 12:48:47 -050030
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070031namespace ndn {
hilatadd50ada2014-03-13 12:48:47 -050032
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070033const static Name LOCALHOP_HUB = "/localhop/ndn-autoconf/hub";
Minsheng Zhang60d06d82015-02-10 14:09:01 -070034const static Name LOCALHOP_ROUTABLE_PREFIXES = "/localhop/nfd/rib/routable-prefixes";
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070035
36static void
hilatadd50ada2014-03-13 12:48:47 -050037usage(const char* programName)
38{
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070039 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"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070043 << "\n"
44 << " Uri - a FaceMgmt URI\n"
45 << std::endl;
hilatadd50ada2014-03-13 12:48:47 -050046}
47
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070048class PrefixCollection : noncopyable
hilatadd50ada2014-03-13 12:48:47 -050049{
50public:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070051 bool
52 empty() const
hilatadd50ada2014-03-13 12:48:47 -050053 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070054 return m_prefixes.empty();
hilatadd50ada2014-03-13 12:48:47 -050055 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070056
hilatadd50ada2014-03-13 12:48:47 -050057 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070058 add(const Name& prefix)
hilatadd50ada2014-03-13 12:48:47 -050059 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070060 m_prefixes.push_back(prefix);
61 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070062
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070063 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
93private:
94 std::vector<Name> m_prefixes;
95};
96
97class NdnAutoconfigServer : noncopyable
98{
99public:
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
Junxiao Shi51493202016-07-23 02:03:08 +0000107 m_hubData->setContent(makeBinaryBlock(tlv::nfd::Uri,
108 reinterpret_cast<const uint8_t*>(hubFaceUri.c_str()),
109 hubFaceUri.size()));
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700110 m_keyChain.sign(*m_hubData);
111
112 // pre-create routable prefix Data
113 if (!routablePrefixes.empty()) {
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700114 Name routablePrefixesDataName(LOCALHOP_ROUTABLE_PREFIXES);
115 routablePrefixesDataName.appendVersion();
116 routablePrefixesDataName.appendSegment(0);
117 m_routablePrefixesData = make_shared<Data>(routablePrefixesDataName);
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700118 m_routablePrefixesData->setContent(routablePrefixes.wireEncode());
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700119 m_routablePrefixesData->setFinalBlockId(routablePrefixesDataName.get(-1));
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700120 m_routablePrefixesData->setFreshnessPeriod(time::seconds(5)); // 5s
121 m_keyChain.sign(*m_routablePrefixesData);
122 }
hilatadd50ada2014-03-13 12:48:47 -0500123 }
124
125 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700126 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)
hilatadd50ada2014-03-13 12:48:47 -0500139 {
140 std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" <<
141 reason << ")" << std::endl;
142 m_face.shutdown();
143 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700144
hilatadd50ada2014-03-13 12:48:47 -0500145 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700146 run()
147 {
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700148 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 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700159
hilatadd50ada2014-03-13 12:48:47 -0500160 m_face.processEvents();
161 }
162
163private:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700164 Face m_face;
hilatadd50ada2014-03-13 12:48:47 -0500165
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700166 shared_ptr<Data> m_hubData;
167 shared_ptr<Data> m_routablePrefixesData;
hilatadd50ada2014-03-13 12:48:47 -0500168};
169
170int
171main(int argc, char** argv)
172{
hilatadd50ada2014-03-13 12:48:47 -0500173 const char* programName = argv[0];
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700174
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700175 PrefixCollection routablePrefixes;
176
177 int opt;
178 while ((opt = getopt(argc, argv, "hVp:")) != -1) {
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700179 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;
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700186 case 'p':
187 routablePrefixes.add(Name(optarg));
188 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700189 default:
190 usage(programName);
191 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500192 }
193 }
194
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700195 if (argc != optind + 1) {
hilatadd50ada2014-03-13 12:48:47 -0500196 usage(programName);
197 return 1;
198 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700199
200 std::string hubFaceUri = argv[optind];
201 NdnAutoconfigServer instance(hubFaceUri, routablePrefixes);
hilatadd50ada2014-03-13 12:48:47 -0500202
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700203 try {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700204 instance.run();
hilatadd50ada2014-03-13 12:48:47 -0500205 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700206 catch (const std::exception& error) {
hilatadd50ada2014-03-13 12:48:47 -0500207 std::cerr << "ERROR: " << error.what() << std::endl;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700208 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500209 }
210 return 0;
211}
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700212
213} // namespace ndn
214
215int
216main(int argc, char** argv)
217{
218 return ndn::main(argc, argv);
219}