blob: 1a01061eb86bd76c133c9f0c7b01d50800b9f8c2 [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 AUTOCONFIG_PREFIX = "/localhop/ndn-autoconf";
32const static Name LOCALHOP_HUB = "/localhop/ndn-autoconf/hub";
33const static Name LOCALHOP_ROUTABLE_PREFIXES = "/localhop/ndn-autoconf/routable-prefixes";
34
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()) {
113 m_routablePrefixesData = make_shared<Data>(Name(LOCALHOP_ROUTABLE_PREFIXES).appendVersion());
114 m_routablePrefixesData->setContent(routablePrefixes.wireEncode());
115 m_routablePrefixesData->setFreshnessPeriod(time::seconds(5)); // 5s
116 m_keyChain.sign(*m_routablePrefixesData);
117 }
hilatadd50ada2014-03-13 12:48:47 -0500118 }
119
120 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700121 onHubInterest(const Name& name, const Interest& interest)
122 {
123 m_face.put(*m_hubData);
124 }
125
126 void
127 onRoutablePrefixesInterest(const Name& name, const Interest& interest)
128 {
129 m_face.put(*m_routablePrefixesData);
130 }
131
132 void
133 onRegisterFailed(const Name& prefix, const std::string& reason)
hilatadd50ada2014-03-13 12:48:47 -0500134 {
135 std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" <<
136 reason << ")" << std::endl;
137 m_face.shutdown();
138 }
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700139
hilatadd50ada2014-03-13 12:48:47 -0500140 void
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700141 afterPrefixRegistered()
hilatadd50ada2014-03-13 12:48:47 -0500142 {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700143 BOOST_ASSERT(AUTOCONFIG_PREFIX.isPrefixOf(LOCALHOP_HUB));
144 m_face.setInterestFilter(LOCALHOP_HUB,
145 bind(&NdnAutoconfigServer::onHubInterest, this, _1, _2));
146
147 if (static_cast<bool>(m_routablePrefixesData)) {
148 BOOST_ASSERT(AUTOCONFIG_PREFIX.isPrefixOf(LOCALHOP_ROUTABLE_PREFIXES));
149 m_face.setInterestFilter(LOCALHOP_ROUTABLE_PREFIXES,
150 bind(&NdnAutoconfigServer::onRoutablePrefixesInterest,
151 this, _1, _2));
152 }
153 }
154
155 void
156 run()
157 {
158 m_face.registerPrefix(AUTOCONFIG_PREFIX,
159 bind(&NdnAutoconfigServer::afterPrefixRegistered, this),
160 bind(&NdnAutoconfigServer::onRegisterFailed, this, _1, _2));
161
hilatadd50ada2014-03-13 12:48:47 -0500162 m_face.processEvents();
163 }
164
165private:
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700166 Face m_face;
hilatadd50ada2014-03-13 12:48:47 -0500167
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700168 shared_ptr<Data> m_hubData;
169 shared_ptr<Data> m_routablePrefixesData;
hilatadd50ada2014-03-13 12:48:47 -0500170};
171
172int
173main(int argc, char** argv)
174{
hilatadd50ada2014-03-13 12:48:47 -0500175 const char* programName = argv[0];
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -0700176
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700177 PrefixCollection routablePrefixes;
178
179 int opt;
180 while ((opt = getopt(argc, argv, "hVp:")) != -1) {
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700181 switch (opt) {
182 case 'h':
183 usage(programName);
184 return 0;
185 case 'V':
186 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
187 return 0;
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700188 case 'p':
189 routablePrefixes.add(Name(optarg));
190 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700191 default:
192 usage(programName);
193 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500194 }
195 }
196
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700197 if (argc != optind + 1) {
hilatadd50ada2014-03-13 12:48:47 -0500198 usage(programName);
199 return 1;
200 }
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700201
202 std::string hubFaceUri = argv[optind];
203 NdnAutoconfigServer instance(hubFaceUri, routablePrefixes);
hilatadd50ada2014-03-13 12:48:47 -0500204
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700205 try {
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700206 instance.run();
hilatadd50ada2014-03-13 12:48:47 -0500207 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700208 catch (const std::exception& error) {
hilatadd50ada2014-03-13 12:48:47 -0500209 std::cerr << "ERROR: " << error.what() << std::endl;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700210 return 1;
hilatadd50ada2014-03-13 12:48:47 -0500211 }
212 return 0;
213}
Yingdi Yu7b0e9cf2014-08-29 14:57:32 -0700214
215} // namespace ndn
216
217int
218main(int argc, char** argv)
219{
220 return ndn::main(argc, argv);
221}