blob: 06d739761e4e8dabe7832799f2cb19ead4f8ae7d [file] [log] [blame]
Shock Jiang698e6ed2014-11-09 11:22:24 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California.
4 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "ndns-label.hpp"
21#include "logger.hpp"
22#include "clients/response.hpp"
23#include "clients/query.hpp"
24#include "clients/iterative-query-controller.hpp"
25#include "validator.hpp"
26
27#include <ndn-cxx/security/key-chain.hpp>
28#include <ndn-cxx/face.hpp>
29#include <boost/program_options.hpp>
30#include <boost/asio.hpp>
31#include <boost/filesystem.hpp>
32#include <boost/noncopyable.hpp>
33
34#include <memory>
35#include <string>
36
37
38namespace ndn {
39namespace ndns {
40NDNS_LOG_INIT("NdnsDig");
41
42class NdnsDig
43{
44public:
45 NdnsDig(const Name& hint, const Name& dstLabel,
46 const name::Component& rrType)
47 : m_dstLabel(dstLabel)
48 , m_rrType(rrType)
49 , m_hint(hint)
50 , m_interestLifetime(DEFAULT_INTEREST_LIFETIME)
51 , m_validator(m_face)
52 , m_ctr(new IterativeQueryController(m_dstLabel, m_rrType, m_interestLifetime,
53 bind(&NdnsDig::onSucceed, this, _1, _2),
54 bind(&NdnsDig::onFail, this, _1, _2),
55 m_face))
56 , m_hasError(false)
57 {
58 }
59
60 void
61 run()
62 {
63 NDNS_LOG_INFO(" =================================== "
64 << "start to dig label = " << this->m_dstLabel
65 << " for type = " << this->m_rrType
66 << " =================================== ");
67
68 try {
69 m_ctr->start(); // non-block, may throw exception
70 m_face.processEvents();
71 }
72 catch (std::exception& e) {
73 NDNS_LOG_FATAL("Error: Face fails to process events: " << e.what());
74 m_hasError = true;
75 }
76 }
77
78 void
79 stop()
80 {
81 m_face.getIoService().stop();
82 NDNS_LOG_TRACE("application stops.");
83 }
84
85private:
86 void
87 onSucceed(const Data& data, const Response& response)
88 {
89 NDNS_LOG_INFO("Dig get following final Response (need verification):");
90 NDNS_LOG_INFO(response);
91 NDNS_LOG_TRACE("to verify the response");
92 m_validator.validate(data,
93 bind(&NdnsDig::onDataValidated, this, _1),
94 bind(&NdnsDig::onDataValidationFailed, this, _1, _2)
95 );
96 }
97
98 void
99 onFail(uint32_t errCode, const std::string& errMsg)
100 {
101 NDNS_LOG_INFO("fail to get response: errCode=" << errCode << " msg=" << errMsg);
102 m_hasError = true;
103 this->stop();
104 }
105
106 void
107 onDataValidated(const shared_ptr<const Data>& data)
108 {
109 NDNS_LOG_INFO("final data pass verification");
110 this->stop();
111 }
112
113 void
114 onDataValidationFailed(const shared_ptr<const Data>& data, const std::string& str)
115 {
116 NDNS_LOG_INFO("final data does not pass verification");
117 m_hasError = true;
118 this->stop();
119 }
120
121public:
122 void
123 setInterestLifetime(const time::milliseconds& lifetime)
124 {
125 m_interestLifetime = lifetime;
126 }
127
128 const bool
129 hasError() const
130 {
131 return m_hasError;
132 }
133
134private:
135 Name m_dstLabel;
136 name::Component m_rrType;
137
138 Name m_hint;
139 Name m_certName;
140 time::milliseconds m_interestLifetime;
141
142 Face m_face;
143
144 Validator m_validator;
145 std::unique_ptr<QueryController> m_ctr;
146
147 bool m_hasError;
148};
149
150} // namespace ndns
151} // namespace ndn
152
153
154int
155main(int argc, char* argv[])
156{
157 ndn::ndns::log::init();
158 using std::string;
159 using namespace ndn;
160
161 Name dstLabel;
162 int ttl = 4;
163 string rrType = "TXT";
164
165 try {
166 namespace po = boost::program_options;
167 po::variables_map vm;
168
169 po::options_description generic("Generic Options");
170 generic.add_options()("help,h", "print help message");
171
172 po::options_description config("Configuration");
173 config.add_options()
174 ("timeout,T", po::value<int>(&ttl), "waiting seconds of query. default: 10 sec")
175 ("rrtype,t", po::value<std::string>(&rrType), "set request RR Type. default: TXT")
176 ;
177
178 po::options_description hidden("Hidden Options");
179 hidden.add_options()
180 ("name", po::value<Name>(&dstLabel), "name to be resolved")
181 ;
182 po::positional_options_description postion;
183 postion.add("name", 1);
184
185 po::options_description cmdline_options;
186 cmdline_options.add(generic).add(config).add(hidden);
187
188 po::options_description config_file_options;
189 config_file_options.add(config).add(hidden);
190
191 po::options_description visible("Allowed options");
192 visible.add(generic).add(config);
193
194 po::parsed_options parsed =
195 po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
196
197 po::store(parsed, vm);
198 po::notify(vm);
199
200 if (vm.count("help")) {
201 std::cout << "Usage: dig /name/to/be/resolved [-t rrType] [-T ttl]" << std::endl;
202 std::cout << visible << std::endl;
203 return 0;
204 }
205 }
206 catch (const std::exception& ex) {
207 std::cerr << "Parameter Error: " << ex.what() << std::endl;
208 return 0;
209 }
210
211 ndn::ndns::NdnsDig dig("", dstLabel, ndn::name::Component(rrType));
212 dig.setInterestLifetime(ndn::time::milliseconds(ttl * 1000));
213
214 dig.run();
215 if (dig.hasError())
216 return 1;
217 else
218 return 0;
219}