blob: ae576f3cd4f17eeb678acab6b611e2dd6dc3de4a [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"
Junxiao Shi0de23a22015-12-03 20:07:02 +000026#include <ndn-cxx/encoding/tlv-nfd.hpp>
Alexander Afanasyev4a771362014-04-24 21:29:33 -070027#include <ndn-cxx/face.hpp>
28#include <ndn-cxx/security/key-chain.hpp>
hilatadd50ada2014-03-13 12:48:47 -050029
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070030namespace ndn {
hilatadd50ada2014-03-13 12:48:47 -050031
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070032const static Name LOCALHOP_HUB = "/localhop/ndn-autoconf/hub";
Minsheng Zhang60d06d82015-02-10 14:09:01 -070033const static Name LOCALHOP_ROUTABLE_PREFIXES = "/localhop/nfd/rib/routable-prefixes";
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070034
35static void
hilatadd50ada2014-03-13 12:48:47 -050036usage(const char* programName)
37{
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070038 std::cout << "Usage:\n" << programName << " [-h] [-V] [-p prefix] [-p prefix] ... Uri \n"
39 << " -h - print usage and exit\n"
40 << " -V - print version number and exit\n"
41 << " -p prefix - the local prefix of the hub\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070042 << "\n"
43 << " Uri - a FaceMgmt URI\n"
44 << std::endl;
hilatadd50ada2014-03-13 12:48:47 -050045}
46
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070047class PrefixCollection : noncopyable
hilatadd50ada2014-03-13 12:48:47 -050048{
49public:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070050 bool
51 empty() const
hilatadd50ada2014-03-13 12:48:47 -050052 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070053 return m_prefixes.empty();
hilatadd50ada2014-03-13 12:48:47 -050054 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070055
hilatadd50ada2014-03-13 12:48:47 -050056 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070057 add(const Name& prefix)
hilatadd50ada2014-03-13 12:48:47 -050058 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070059 m_prefixes.push_back(prefix);
60 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070061
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -070062 template<bool T>
63 size_t
64 wireEncode(EncodingImpl<T>& encoder) const
65 {
66 size_t totalLength = 0;
67
68 for (std::vector<Name>::const_reverse_iterator i = m_prefixes.rbegin();
69 i != m_prefixes.rend(); ++i) {
70 totalLength += i->wireEncode(encoder);
71 }
72
73 totalLength += encoder.prependVarNumber(totalLength);
74 totalLength += encoder.prependVarNumber(tlv::Content);
75 return totalLength;
76 }
77
78 Block
79 wireEncode() const
80 {
81 Block block;
82
83 EncodingEstimator estimator;
84 size_t estimatedSize = wireEncode(estimator);
85
86 EncodingBuffer buffer(estimatedSize);
87 wireEncode(buffer);
88
89 return buffer.block();
90 }
91
92private:
93 std::vector<Name> m_prefixes;
94};
95
96class NdnAutoconfigServer : noncopyable
97{
98public:
99 NdnAutoconfigServer(const std::string& hubFaceUri, const PrefixCollection& routablePrefixes)
100 {
101 KeyChain m_keyChain;
102
103 // pre-create hub Data
104 m_hubData = make_shared<Data>(Name(LOCALHOP_HUB).appendVersion());
105 m_hubData->setFreshnessPeriod(time::hours(1)); // 1 hour
106 m_hubData->setContent(dataBlock(tlv::nfd::Uri,
107 reinterpret_cast<const uint8_t*>(hubFaceUri.c_str()),
108 hubFaceUri.size()));
109 m_keyChain.sign(*m_hubData);
110
111 // pre-create routable prefix Data
112 if (!routablePrefixes.empty()) {
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700113 Name routablePrefixesDataName(LOCALHOP_ROUTABLE_PREFIXES);
114 routablePrefixesDataName.appendVersion();
115 routablePrefixesDataName.appendSegment(0);
116 m_routablePrefixesData = make_shared<Data>(routablePrefixesDataName);
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700117 m_routablePrefixesData->setContent(routablePrefixes.wireEncode());
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700118 m_routablePrefixesData->setFinalBlockId(routablePrefixesDataName.get(-1));
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700119 m_routablePrefixesData->setFreshnessPeriod(time::seconds(5)); // 5s
120 m_keyChain.sign(*m_routablePrefixesData);
121 }
hilatadd50ada2014-03-13 12:48:47 -0500122 }
123
124 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700125 onHubInterest(const Name& name, const Interest& interest)
126 {
127 m_face.put(*m_hubData);
128 }
129
130 void
131 onRoutablePrefixesInterest(const Name& name, const Interest& interest)
132 {
133 m_face.put(*m_routablePrefixesData);
134 }
135
136 void
137 onRegisterFailed(const Name& prefix, const std::string& reason)
hilatadd50ada2014-03-13 12:48:47 -0500138 {
139 std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" <<
140 reason << ")" << std::endl;
141 m_face.shutdown();
142 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700143
hilatadd50ada2014-03-13 12:48:47 -0500144 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700145 run()
146 {
Minsheng Zhang60d06d82015-02-10 14:09:01 -0700147 m_face.setInterestFilter(LOCALHOP_HUB,
148 bind(&NdnAutoconfigServer::onHubInterest, this, _1, _2),
149 RegisterPrefixSuccessCallback(),
150 bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
151
152 if (static_cast<bool>(m_routablePrefixesData)) {
153 m_face.setInterestFilter(LOCALHOP_ROUTABLE_PREFIXES,
154 bind(&NdnAutoconfigServer::onRoutablePrefixesInterest, this, _1, _2),
155 RegisterPrefixSuccessCallback(),
156 bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
157 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700158
hilatadd50ada2014-03-13 12:48:47 -0500159 m_face.processEvents();
160 }
161
162private:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700163 Face m_face;
hilatadd50ada2014-03-13 12:48:47 -0500164
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700165 shared_ptr<Data> m_hubData;
166 shared_ptr<Data> m_routablePrefixesData;
hilatadd50ada2014-03-13 12:48:47 -0500167};
168
169int
170main(int argc, char** argv)
171{
hilatadd50ada2014-03-13 12:48:47 -0500172 const char* programName = argv[0];
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700173
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700174 PrefixCollection routablePrefixes;
175
176 int opt;
177 while ((opt = getopt(argc, argv, "hVp:")) != -1) {
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700178 switch (opt) {
179 case 'h':
180 usage(programName);
181 return 0;
182 case 'V':
183 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
184 return 0;
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700185 case 'p':
186 routablePrefixes.add(Name(optarg));
187 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700188 default:
189 usage(programName);
190 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500191 }
192 }
193
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700194 if (argc != optind + 1) {
hilatadd50ada2014-03-13 12:48:47 -0500195 usage(programName);
196 return 1;
197 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700198
199 std::string hubFaceUri = argv[optind];
200 NdnAutoconfigServer instance(hubFaceUri, routablePrefixes);
hilatadd50ada2014-03-13 12:48:47 -0500201
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700202 try {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700203 instance.run();
hilatadd50ada2014-03-13 12:48:47 -0500204 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700205 catch (const std::exception& error) {
hilatadd50ada2014-03-13 12:48:47 -0500206 std::cerr << "ERROR: " << error.what() << std::endl;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700207 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500208 }
209 return 0;
210}
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700211
212} // namespace ndn
213
214int
215main(int argc, char** argv)
216{
217 return ndn::main(argc, argv);
218}