blob: 728d0b0b1bd3d8e67b31448cde4ba130969b26f4 [file] [log] [blame]
shockjianga5ae48c2014-07-27 23:21:41 -07001/* -*- 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#include "name-caching-resolver.hpp"
20
21namespace ndn {
22namespace ndns {
23
24NameCachingResolver::NameCachingResolver(const char *programName, const char *prefix)
25: NDNApp(programName, prefix)
26//, m_resolverType(CachingResolver)
27{
28 this->setInterestLifetime(time::milliseconds(2000));
29}
30
31
32
33void
34NameCachingResolver::run()
35{
36 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
37 signalSet.async_wait(boost::bind(&NDNApp::signalHandler, this));
38 // boost::bind(&NdnTlvPingServer::signalHandler, this)
39
40 Name name(m_prefix);
41 name.append(Query::toString(Query::QUERY_DNS_R));
42
43 m_face.setInterestFilter(name,
44 bind(&NameCachingResolver::onInterest,
45 this, _1, _2),
46 bind(&NDNApp::onRegisterFailed,
47 this, _1,_2));
48
49 std::cout << "\n=== NDNS Resolver "<<m_programName
50 <<" with routeble prefix "<< name.toUri()
51 << " starts===\n" << std::endl;
52
53 try {
54 m_face.processEvents();
55 }
56 catch (std::exception& e) {
57 std::cerr << "ERROR: " << e.what() << std::endl;
58 m_hasError = true;
59 m_ioService.stop();
60 }
61}
62
63
64
65void
66NameCachingResolver::onData(const Interest& interest, Data &data, IterativeQuery& iq)
67{
68 if (interest.getName() != iq.getLastInterest().getName())
69 {
70 std::cout<<iq<<std::endl;
71 std::cout<<"waiting for "<<iq.getLastInterest().getName().toUri()<<std::endl;
72 std::cout<<"coming data "<<data.getName().toUri()<<std::endl;
73 return;
74 }
75
76 iq.doData(data);
77
78 if (iq.getStep() == IterativeQuery::AnswerStub)
79 {
80 Data data = iq.getLastResponse().toData();
81 Name name = iq.getQuery().getAuthorityZone();
82 name.append(Query::toString(iq.getQuery().getQueryType()));
83 name.append(iq.getQuery().getRrLabel());
84 name.append(RR::toString(iq.getQuery().getRrType()));
85 name.appendVersion();
86 data.setName(name);
87 data.setFreshnessPeriod(iq.getLastResponse().getFreshness());
88
89 m_keyChain.sign(data);
90 m_face.put(data);
91 std::cout<<"[* <- *] answer Response ("
92 <<Response::toString(iq.getLastResponse().getResponseType())<<") to stub:"<<std::endl;
93 std::cout<<iq.getLastResponse()<<std::endl;
94 for (int i=0; i<15; i++)
95 {
96 std::cout<<"----";
97 }
98 std::cout<<std::endl<<std::endl;
99
100 } else if (iq.getStep() == IterativeQuery::NSQuery){
101 resolve(iq);
102 } else if (iq.getStep() == IterativeQuery::RRQuery) {
103 resolve(iq);
104 } else if (iq.getStep() == IterativeQuery::Abort) {
105 return;
106 } else {
107 std::cout<<"let me see the current step="<<IterativeQuery::toString(iq.getStep())<<std::endl;
108 std::cout<<iq<<std::endl;
109 }
110
111}
112
113
114void
115NameCachingResolver::answerRespNack(IterativeQuery& iq)
116{
117 Response re;
118
119 Name name = iq.getQuery().getAuthorityZone();
120 name.append(Query::toString(iq.getQuery().getQueryType()));
121 name.append(iq.getQuery().getRrLabel());
122 name.append(RR::toString(iq.getQuery().getRrType()));
123 name.appendVersion();
124
125 re.setResponseType(Response::NDNS_Nack);
126 re.setFreshness(this->getContentFreshness());
127 re.setQueryName(name);
128 Data data = re.toData();
129
130 m_keyChain.sign(data);
131 m_face.put(data);
132 std::cout<<"[* <- *] answer RRs to stub:"<<std::endl;
133 std::cout<<iq.getLastResponse().getStringRRs()<<std::endl;
134 for (int i=0; i<15; i++)
135 {
136 std::cout<<"----";
137 }
138 std::cout<<std::endl<<std::endl;
139}
140
141void
142NameCachingResolver::onInterest(const Name &name, const Interest &interest)
143{
144 Query query;
145 query.fromInterest(interest);
146 std::cout<<"[* -> *] receive Interest: "<<interest.getName().toUri()<<std::endl;
147 if (query.getQueryType() == Query::QUERY_DNS)
148 {
149 cout<<m_programName<<" is not in charge of Query_DNS"<<endl;
150 }
151
152 IterativeQuery iq(query);
153 //iq.setQuery(query);
154 resolve(iq);
155
156}
157
158
159void
160NameCachingResolver::onTimeout(const Interest& interest, IterativeQuery& iq)
161{
162 std::cout<<"[* !! *] timeout Interest "<<interest.getName().toUri()<<" timeouts"<<std::endl;
163
164 iq.doTimeout();
165 return;
166}
167
168void
169NameCachingResolver::resolve(IterativeQuery& iq) {
170
171 Interest interest = iq.toLatestInterest();
172
173 //must be set before express interest,since the call will back call iq
174 //if set after, then the iq in call of onData will return nothing
175 //be very careful here, as a new guy to c++
176
177 interest.setInterestLifetime(this->getInterestLifetime());
178 iq.setLastInterest(interest);
179 try {
180 m_face.expressInterest(interest,
181 boost::bind(&NameCachingResolver::onData, this, _1, _2, iq),
182 boost::bind(&NameCachingResolver::onTimeout, this, _1, iq)
183 );
184 }catch(std::exception& e) {
185 std::cerr << "ERROR: " << e.what() << std::endl;
186 }
187
188
189 std::cout<<"[* <- *] send Interest: "<<interest.getName().toUri()<<std::endl;
190 std::cout<<iq<<std::endl;
191}
192
193} /* namespace ndns */
194} /* namespace ndn */