blob: fa4b2e7ae14bd35e1dc09cc81e183a15d3d80b61 [file] [log] [blame]
hilatadd50ada2014-03-13 12:48:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
hilatadd50ada2014-03-13 12:48:47 -050024
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070025#include "version.hpp"
Alexander Afanasyev4a771362014-04-24 21:29:33 -070026#include <ndn-cxx/face.hpp>
27#include <ndn-cxx/security/key-chain.hpp>
hilatadd50ada2014-03-13 12:48:47 -050028
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070029namespace ndn {
hilatadd50ada2014-03-13 12:48:47 -050030
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070031const static Name LOCALHOP_HUB = "/localhop/ndn-autoconf/hub";
Minsheng Zhang60d06d82015-02-10 14:09:01 -070032const static Name LOCALHOP_ROUTABLE_PREFIXES = "/localhop/nfd/rib/routable-prefixes";
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070033
34static void
hilatadd50ada2014-03-13 12:48:47 -050035usage(const char* programName)
36{
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070037 std::cout << "Usage:\n" << programName << " [-h] [-V] [-p prefix] [-p prefix] ... Uri \n"
38 << " -h - print usage and exit\n"
39 << " -V - print version number and exit\n"
40 << " -p prefix - the local prefix of the hub\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070041 << "\n"
42 << " Uri - a FaceMgmt URI\n"
43 << std::endl;
hilatadd50ada2014-03-13 12:48:47 -050044}
45
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070046class PrefixCollection : noncopyable
hilatadd50ada2014-03-13 12:48:47 -050047{
48public:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070049 bool
50 empty() const
hilatadd50ada2014-03-13 12:48:47 -050051 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070052 return m_prefixes.empty();
hilatadd50ada2014-03-13 12:48:47 -050053 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070054
hilatadd50ada2014-03-13 12:48:47 -050055 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070056 add(const Name& prefix)
hilatadd50ada2014-03-13 12:48:47 -050057 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070058 m_prefixes.push_back(prefix);
59 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070060
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070061 template<bool T>
62 size_t
63 wireEncode(EncodingImpl<T>& encoder) const
64 {
65 size_t totalLength = 0;
66
67 for (std::vector<Name>::const_reverse_iterator i = m_prefixes.rbegin();
68 i != m_prefixes.rend(); ++i) {
69 totalLength += i->wireEncode(encoder);
70 }
71
72 totalLength += encoder.prependVarNumber(totalLength);
73 totalLength += encoder.prependVarNumber(tlv::Content);
74 return totalLength;
75 }
76
77 Block
78 wireEncode() const
79 {
80 Block block;
81
82 EncodingEstimator estimator;
83 size_t estimatedSize = wireEncode(estimator);
84
85 EncodingBuffer buffer(estimatedSize);
86 wireEncode(buffer);
87
88 return buffer.block();
89 }
90
91private:
92 std::vector<Name> m_prefixes;
93};
94
95class NdnAutoconfigServer : noncopyable
96{
97public:
98 NdnAutoconfigServer(const std::string& hubFaceUri, const PrefixCollection& routablePrefixes)
99 {
100 KeyChain m_keyChain;
101
102 // pre-create hub Data
103 m_hubData = make_shared<Data>(Name(LOCALHOP_HUB).appendVersion());
104 m_hubData->setFreshnessPeriod(time::hours(1)); // 1 hour
105 m_hubData->setContent(dataBlock(tlv::nfd::Uri,
106 reinterpret_cast<const uint8_t*>(hubFaceUri.c_str()),
107 hubFaceUri.size()));
108 m_keyChain.sign(*m_hubData);
109
110 // pre-create routable prefix Data
111 if (!routablePrefixes.empty()) {
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700112 Name routablePrefixesDataName(LOCALHOP_ROUTABLE_PREFIXES);
113 routablePrefixesDataName.appendVersion();
114 routablePrefixesDataName.appendSegment(0);
115 m_routablePrefixesData = make_shared<Data>(routablePrefixesDataName);
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700116 m_routablePrefixesData->setContent(routablePrefixes.wireEncode());
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700117 m_routablePrefixesData->setFinalBlockId(routablePrefixesDataName.get(-1));
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700118 m_routablePrefixesData->setFreshnessPeriod(time::seconds(5)); // 5s
119 m_keyChain.sign(*m_routablePrefixesData);
120 }
hilatadd50ada2014-03-13 12:48:47 -0500121 }
122
123 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700124 onHubInterest(const Name& name, const Interest& interest)
125 {
126 m_face.put(*m_hubData);
127 }
128
129 void
130 onRoutablePrefixesInterest(const Name& name, const Interest& interest)
131 {
132 m_face.put(*m_routablePrefixesData);
133 }
134
135 void
136 onRegisterFailed(const Name& prefix, const std::string& reason)
hilatadd50ada2014-03-13 12:48:47 -0500137 {
138 std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" <<
139 reason << ")" << std::endl;
140 m_face.shutdown();
141 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700142
hilatadd50ada2014-03-13 12:48:47 -0500143 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700144 run()
145 {
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700146 m_face.setInterestFilter(LOCALHOP_HUB,
147 bind(&NdnAutoconfigServer::onHubInterest, this, _1, _2),
148 RegisterPrefixSuccessCallback(),
149 bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
150
151 if (static_cast<bool>(m_routablePrefixesData)) {
152 m_face.setInterestFilter(LOCALHOP_ROUTABLE_PREFIXES,
153 bind(&NdnAutoconfigServer::onRoutablePrefixesInterest, this, _1, _2),
154 RegisterPrefixSuccessCallback(),
155 bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
156 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700157
hilatadd50ada2014-03-13 12:48:47 -0500158 m_face.processEvents();
159 }
160
161private:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700162 Face m_face;
hilatadd50ada2014-03-13 12:48:47 -0500163
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700164 shared_ptr<Data> m_hubData;
165 shared_ptr<Data> m_routablePrefixesData;
hilatadd50ada2014-03-13 12:48:47 -0500166};
167
168int
169main(int argc, char** argv)
170{
hilatadd50ada2014-03-13 12:48:47 -0500171 const char* programName = argv[0];
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700172
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700173 PrefixCollection routablePrefixes;
174
175 int opt;
176 while ((opt = getopt(argc, argv, "hVp:")) != -1) {
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700177 switch (opt) {
178 case 'h':
179 usage(programName);
180 return 0;
181 case 'V':
182 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
183 return 0;
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700184 case 'p':
185 routablePrefixes.add(Name(optarg));
186 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700187 default:
188 usage(programName);
189 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500190 }
191 }
192
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700193 if (argc != optind + 1) {
hilatadd50ada2014-03-13 12:48:47 -0500194 usage(programName);
195 return 1;
196 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700197
198 std::string hubFaceUri = argv[optind];
199 NdnAutoconfigServer instance(hubFaceUri, routablePrefixes);
hilatadd50ada2014-03-13 12:48:47 -0500200
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700201 try {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700202 instance.run();
hilatadd50ada2014-03-13 12:48:47 -0500203 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700204 catch (const std::exception& error) {
hilatadd50ada2014-03-13 12:48:47 -0500205 std::cerr << "ERROR: " << error.what() << std::endl;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700206 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500207 }
208 return 0;
209}
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700210
211} // namespace ndn
212
213int
214main(int argc, char** argv)
215{
216 return ndn::main(argc, argv);
217}