blob: d2b679f5884bb7faf3952fdace7b823390f5dea3 [file] [log] [blame]
Andrea Tosatto672b9a72016-01-05 16:18:20 +01001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2016, Regents of the University of California,
4 * Colorado State University,
5 * University Pierre & Marie Curie, Sorbonne University.
6 *
7 * This file is part of ndn-tools (Named Data Networking Essential Tools).
8 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
9 *
10 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
22 *
23 * @author Wentao Shang
24 * @author Steve DiBenedetto
25 * @author Andrea Tosatto
26 */
27
28#include "core/version.hpp"
29#include "options.hpp"
30#include "consumer.hpp"
31#include "discover-version-fixed.hpp"
32#include "discover-version-iterative.hpp"
33
34#include <ndn-cxx/security/validator-null.hpp>
35
36namespace ndn {
37namespace chunks {
38
39static int
40main(int argc, char** argv)
41{
42 std::string programName(argv[0]);
43 Options options;
44 std::string discoverType("fixed");
45 size_t maxPipelineSize(1);
46 int maxRetriesAfterVersionFound(1);
47 std::string uri;
48
49 namespace po = boost::program_options;
50 po::options_description visibleDesc("Options");
51 visibleDesc.add_options()
52 ("help,h", "print this help message and exit")
53 ("discover-version,d", po::value<std::string>(&discoverType)->default_value(discoverType),
54 "version discovery algorithm to use; valid values are: 'fixed', 'iterative'")
55 ("fresh,f", po::bool_switch(&options.mustBeFresh), "only return fresh content")
56 ("lifetime,l", po::value<uint64_t>()->default_value(options.interestLifetime.count()),
57 "lifetime of expressed Interests, in milliseconds")
58 ("pipeline,p", po::value<size_t>(&maxPipelineSize)->default_value(maxPipelineSize),
59 "maximum size of the Interest pipeline")
60 ("retries,r", po::value<int>(&options.maxRetriesOnTimeoutOrNack)->default_value(options.maxRetriesOnTimeoutOrNack),
61 "maximum number of retries in case of Nack or timeout (-1 = no limit)")
62 ("retries-iterative,i", po::value<int>(&maxRetriesAfterVersionFound)->default_value(maxRetriesAfterVersionFound),
63 "number of timeouts that have to occur in order to confirm a discovered Data "
64 "version as the latest one (only applicable to 'iterative' version discovery)")
65 ("verbose,v", po::bool_switch(&options.isVerbose), "turn on verbose output")
66 ("version,V", "print program version and exit")
67 ;
68
69 po::options_description hiddenDesc("Hidden options");
70 hiddenDesc.add_options()
71 ("ndn-name,n", po::value<std::string>(&uri), "NDN name of the requested content");
72
73 po::positional_options_description p;
74 p.add("ndn-name", -1);
75
76 po::options_description optDesc("Allowed options");
77 optDesc.add(visibleDesc).add(hiddenDesc);
78
79 po::variables_map vm;
80 try {
81 po::store(po::command_line_parser(argc, argv).options(optDesc).positional(p).run(), vm);
82 po::notify(vm);
83 }
84 catch (const po::error& e) {
85 std::cerr << "ERROR: " << e.what() << std::endl;
86 return 2;
87 }
88 catch (const boost::bad_any_cast& e) {
89 std::cerr << "ERROR: " << e.what() << std::endl;
90 return 2;
91 }
92
93 if (vm.count("help") > 0) {
94 std::cout << "Usage: " << programName << " [options] ndn:/name" << std::endl;
95 std::cout << visibleDesc;
96 return 0;
97 }
98
99 if (vm.count("version") > 0) {
100 std::cout << "ndncatchunks " << tools::VERSION << std::endl;
101 return 0;
102 }
103
104 if (vm.count("ndn-name") == 0) {
105 std::cerr << "Usage: " << programName << " [options] ndn:/name" << std::endl;
106 std::cerr << visibleDesc;
107 return 2;
108 }
109
110 Name prefix(uri);
111 if (discoverType == "fixed" && (prefix.empty() || !prefix[-1].isVersion())) {
112 std::cerr << "ERROR: The specified name must contain a version component when using "
113 "fixed version discovery" << std::endl;
114 return 2;
115 }
116
117 if (maxPipelineSize < 1 || maxPipelineSize > 1024) {
118 std::cerr << "ERROR: pipeline size must be between 1 and 1024" << std::endl;
119 return 2;
120 }
121
122 if (options.maxRetriesOnTimeoutOrNack < -1 || options.maxRetriesOnTimeoutOrNack > 1024) {
123 std::cerr << "ERROR: retries value must be between -1 and 1024" << std::endl;
124 return 2;
125 }
126
127 if (maxRetriesAfterVersionFound < 0 || maxRetriesAfterVersionFound > 1024) {
128 std::cerr << "ERROR: retries iterative value must be between 0 and 1024" << std::endl;
129 return 2;
130 }
131
132 options.interestLifetime = time::milliseconds(vm["lifetime"].as<uint64_t>());
133
134 try {
135 Face face;
136
137 unique_ptr<DiscoverVersion> discover;
138 if (discoverType == "fixed") {
139 discover = make_unique<DiscoverVersionFixed>(prefix, face, options);
140 }
141 else if (discoverType == "iterative") {
142 DiscoverVersionIterative::Options optionsIterative(options);
143 optionsIterative.maxRetriesAfterVersionFound = maxRetriesAfterVersionFound;
144 discover = make_unique<DiscoverVersionIterative>(prefix, face, optionsIterative);
145 }
146 else {
147 std::cerr << "ERROR: discover version type not valid" << std::endl;
148 return 2;
149 }
150
151 ValidatorNull validator;
152 Consumer consumer(face, validator, options.isVerbose);
153
154 PipelineInterests::Options optionsPipeline(options);
155 optionsPipeline.maxPipelineSize = maxPipelineSize;
156 PipelineInterests pipeline(face, optionsPipeline);
157
158 BOOST_ASSERT(discover != nullptr);
159 consumer.run(*discover, pipeline);
160 }
161 catch (const Consumer::ApplicationNackError& e) {
162 std::cerr << "ERROR: " << e.what() << std::endl;
163 return 3;
164 }
165 catch (const std::exception& e) {
166 std::cerr << "ERROR: " << e.what() << std::endl;
167 return 1;
168 }
169
170 return 0;
171}
172
173} // namespace chunks
174} // namespace ndn
175
176int
177main(int argc, char** argv)
178{
179 return ndn::chunks::main(argc, argv);
180}