basic framework, waiting for Alex's comments
diff --git a/src/ndns-tlv.h b/src/ndns-tlv.h
new file mode 100644
index 0000000..d8535a5
--- /dev/null
+++ b/src/ndns-tlv.h
@@ -0,0 +1,16 @@
+
+
+
+namespace ndn {
+namespace tlv {
+namespace ndns {
+ enum {
+ Type = 2000,
+ Fressness = 2001,
+ ContentBlob = 2002,
+ NumberOfRRData = 2003,
+ RRData = 2004
+ };//enum
+}//namespace ndns
+}//namespace tlv
+}//namespace ndn
diff --git a/src/query.cpp b/src/query.cpp
new file mode 100644
index 0000000..861d1c8
--- /dev/null
+++ b/src/query.cpp
@@ -0,0 +1,85 @@
+/*
+ * query.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "query.h"
+
+namespace ndn {
+
+Query::Query()
+: m_interestLifetime(time::milliseconds(4000))
+{
+ // TODO Auto-generated constructor stub
+
+}
+
+Query::~Query() {
+ // TODO Auto-generated destructor stub
+}
+
+
+void
+Query::fromWire(const Name &name, const Interest &interest)
+{
+ Name interestName;
+ interestName = interest.getName();
+
+ int qtflag = -1;
+ size_t len = interestName.size();
+ for (size_t i=0; i<len; i++)
+ {
+ string comp = interestName.get(i).toEscapedString();
+ if (comp == ndn::toString(QueryType::DNS) || comp == ndn::toString(QueryType::DNS_R))
+ {
+ qtflag = i;
+ break;
+ }
+ }//for
+
+ if (qtflag == -1)
+ {
+ cerr<<"There is no QueryType in the Interest Name: "<<interestName<<endl;
+ return;
+ }
+ this->m_queryType = ndn::toQueryType(interestName.get(qtflag).toEscapedString());
+ this->m_rrType = ndn::toRRType(interestName.get(len-1).toEscapedString());
+ this->m_authorityZone = interestName.getPrefix(qtflag); //the DNS/DNS-R is not included
+ this->m_interestLifetime = interest.getInterestLifetime();
+
+}
+
+template<bool T>
+size_t
+Query::wireEncode(EncodingImpl<T>& block) const
+{
+ size_t totalLength = 0;
+ totalLength += 0;
+
+
+ size_t totalLength = prependByteArrayBlock(block, tlv::Bytes,
+ m_key.get().buf(), m_key.get().size());
+ totalLength += m_keyName.wireEncode(block);
+ totalLength += block.prependVarNumber(totalLength);
+ totalLength += block.prependVarNumber(tlv::PublicKey);
+
+ return totalLength;
+}
+
+Interest
+Query::toWire() const
+{
+ Name name = this->m_authorityZone;
+ name.append(ndn::toString(this->m_queryType));
+ name.append(this->m_rrLabel);
+ name.append(ndn::toString(this->m_rrType));
+ Selectors selector;
+ //selector.setMustBeFresh(true);
+
+ Interest interest = Interest(name, selector, -1, this->m_interestLifetime);
+ return interest;
+}
+
+} /* namespace ndn */
diff --git a/src/query.h b/src/query.h
new file mode 100644
index 0000000..001efa0
--- /dev/null
+++ b/src/query.h
@@ -0,0 +1,152 @@
+/*
+ * query.h
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#ifndef QUERY_H_
+#define QUERY_H_
+
+#include <ndn-cxx/name.hpp>
+#include <rr.h>
+
+using namespace std;
+
+namespace ndn {
+
+
+enum class QueryType
+{
+ DNS,
+ DNS_R,
+};
+
+static const string
+toString(QueryType qType) const
+{
+ string label;
+ switch (qType)
+ {
+ case QueryType::DNS:
+ label = "DNS";
+ break;
+ case QueryType::DNS_R:
+ label = "DNS-R";
+ break;
+ default:
+ label = "Default";
+ break;
+ }
+ return label;
+
+}
+
+static const QueryType
+toQueryType(string str)
+{
+ QueryType atype;
+ switch (str)
+ {
+ case "DNS":
+ atype = QueryType::DNS;
+ break;
+ case "DNS-R":
+ atype = QueryType::DNS_R;
+ break;
+ defalut:
+ atype = QueryType::DNS;
+ break;
+ }
+ return atype;
+}
+
+
+
+
+class Query {
+public:
+ Query();
+
+ virtual ~Query();
+
+
+
+ const Name& getAuthorityZone() const {
+ return m_authorityZone;
+ }
+
+ void setAuthorityZone(const Name& authorityZone) {
+ m_authorityZone = authorityZone;
+ }
+
+ time::milliseconds getInterestLifetime() const {
+ return m_interestLifetime;
+ }
+
+ void setInterestLifetime(time::milliseconds interestLifetime) {
+ m_interestLifetime = interestLifetime;
+ }
+
+ enum QueryType getQueryType() const {
+ return m_queryType;
+ }
+
+ void setQueryType(enum QueryType queryType) {
+ m_queryType = queryType;
+ }
+
+ const Name& getRrLabel() const {
+ return m_rrLabel;
+ }
+
+ void setRrLabel(const Name& rrLabel) {
+ m_rrLabel = rrLabel;
+ }
+
+ const RRType& getRrType() const {
+ return m_rrType;
+ }
+
+ void setRrType(const RRType& rrType) {
+ m_rrType = rrType;
+ }
+
+private:
+template<bool T>
+size_t
+wireEncode(EncodingImpl<T> & block) const;
+
+public:
+
+const Block&
+wireEncode() const;
+
+void
+wireDecode(const Block& wire);
+
+
+Interest
+toWire() const;
+
+void
+fromWire(const Name &name, const Interest& interest);
+
+
+
+
+
+public:
+ Name m_authorityZone;
+ enum QueryType m_queryType;
+ time::milliseconds m_interestLifetime;
+ Name m_rrLabel;
+ enum RRType m_rrType;
+
+ mutable Block m_wire;
+ //bool hasWire;
+};
+
+} /* namespace ndn */
+
+#endif /* QUERY_H_ */
diff --git a/src/resolver.cpp b/src/resolver.cpp
new file mode 100644
index 0000000..39da63d
--- /dev/null
+++ b/src/resolver.cpp
@@ -0,0 +1,26 @@
+/*
+ * resolver.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "resolver.h"
+
+namespace ndn {
+
+Resolver::Resolver() {
+ // TODO Auto-generated constructor stub
+
+}
+
+Resolver::~Resolver() {
+ // TODO Auto-generated destructor stub
+}
+const RR Resolver::iterativelyResolve(const string domain, const string name){
+ return "ex";
+}
+const RR Resolver::recusivelyResolve(const string domain, const string name){
+ return "ex";
+}
+} /* namespace ndn */
diff --git a/src/resolver.h b/src/resolver.h
new file mode 100644
index 0000000..1dcdd6d
--- /dev/null
+++ b/src/resolver.h
@@ -0,0 +1,32 @@
+/*
+ * resolver.h
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#ifndef RESOLVER_H_
+#define RESOLVER_H_
+
+#include <string>
+#include "rr.h"
+
+
+using namespace std;
+
+namespace ndn {
+
+class Resolver {
+public:
+ Resolver();
+ virtual ~Resolver();
+
+
+ const RR iterativelyResolve(const string domain, const string name);
+ const RR recusivelyResolve(const string domain, const string name);
+
+};
+
+} /* namespace ndn */
+
+#endif /* RESOLVER_H_ */
diff --git a/src/response.cpp b/src/response.cpp
new file mode 100644
index 0000000..a4c7746
--- /dev/null
+++ b/src/response.cpp
@@ -0,0 +1,121 @@
+/*
+ * response.cpp
+ *
+ * Created on: 19 Jul, 2014
+ * Author: shock
+ */
+
+#include "response.h"
+
+
+
+namespace ndn {
+
+Response::Response() {
+ // TODO Auto-generated constructor stub
+
+}
+
+Response::~Response() {
+ // TODO Auto-generated destructor stub
+}
+
+
+
+Data
+Response::toWire() const
+{
+ Name name = this->m_queryName;
+ name.append(this->m_serial);
+
+ Data data(name);
+
+ data.setFreshnessPeriod(this->m_freshness);
+
+ string content = "";
+
+ size_t totalLen = 0;
+ Block block = Block();
+ block.push_back
+ (nonNegativeIntegerBlock
+ (tlv::ndns::Type, static_cast<unsigned long>(this->m_responseType))
+ );
+
+ block.push_back
+ (nonNegativeIntegerBlock
+ (tlv::ndns::Fressness, this->m_freshness.count())
+ );
+
+ Block block2 = Block(tlv::ndns::ContentBlob);
+ block2.push_back
+ (nonNegativeIntegerBlock
+ (tlv::ndns::NumberOfRRData, this->m_numberOfRR)
+ );
+
+ for (int i=0; i<this->m_numberOfRR; i++)
+ {
+ RR rr = m_rrs[i];
+ block2.push_back(rr.toWire());
+ }
+
+ block.push_back(block2);
+
+ return data;
+
+}
+
+void
+Response::fromWire(const Interest &interest, const Data &data)
+{
+ Name dataName;
+ dataName = data.getName();
+
+ int qtflag = -1;
+ size_t len = dataName.size();
+ for (size_t i=0; i<len; i++)
+ {
+ string comp = dataName.get(i).toEscapedString();
+ if (comp == ndn::toString(QueryType::DNS) || comp == ndn::toString(QueryType::DNS_R))
+ {
+ qtflag = i;
+ break;
+ }
+ }//for
+
+ if (qtflag == -1)
+ {
+ cerr<<"There is no QueryType in the Interest Name: "<<dataName<<endl;
+ return;
+ }
+
+ this->m_queryName = dataName.getPrefix(-1);
+
+ string last = dataName.get(len-1).toEscapedString();
+ if (ndn::toRRType(last) == RRType::UNKNOWN)
+ {
+ this->m_serial = "";
+ } else
+ {
+ this->m_serial = last;
+ }
+
+ Block block = data.getContent();
+ this->m_numberOfRR = readNonNegativeInteger(block.get(tlv::ndns::NumberOfRRData));
+
+ Block block2 = block.get(tlv::ndns::ContentBlob);
+ for (int i=0; i<this->m_numberOfRR; i++)
+ {
+ Block block3 = block2.get(tlv::ndns::RRData);
+ RR rr;
+ rr.fromWire(block3);
+ m_rrs.push_back(rr);
+ }
+
+}
+
+
+} /* namespace ndn */
+
+
+
+
diff --git a/src/response.h b/src/response.h
new file mode 100644
index 0000000..52e11c6
--- /dev/null
+++ b/src/response.h
@@ -0,0 +1,89 @@
+/*
+ * response.h
+ *
+ * Created on: 19 Jul, 2014
+ * Author: shock
+ */
+
+#ifndef RESPONSE_H_
+#define RESPONSE_H_
+
+#include <boost/asio.hpp> // /opt/local/include
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/noncopyable.hpp>
+
+#include <ndn-cxx/face.hpp> // /usr/local/include
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/data.hpp>
+
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/tlv-ndnd.hpp>
+
+#include<vector>
+
+#include "ndns-tlv.h"
+
+using namespace std;
+
+namespace ndn {
+
+
+
+enum class ResponseType
+{
+ NDNS_Resp,
+ NDNS_Nack,
+ NDNS_Auth
+};
+
+
+static const string
+toString(ResponseType responseType) const
+{
+ string label;
+ switch (responseType)
+ {
+ case ResponseType::NDNS_Resp:
+ label = "NDNS Resp";
+ break;
+ case ResponseType::NDNS_Nack:
+ label = "NDNS Nack";
+ break;
+ case ResponseType::NDNS_Auth:
+ label = "NDNS Auth";
+ break;
+ default:
+ label = "Default";
+ break;
+ }
+ return label;
+}
+
+class Response {
+public:
+ Response();
+ virtual ~Response();
+
+Data
+toWire() const;
+
+void
+fromWire(const Interest &interest, const Data &data);
+
+private:
+ Name m_queryName;
+ string m_serial;
+ ResponseType m_responseType;
+
+ time::milliseconds m_freshness;
+
+ unsigned int m_numberOfRR;
+ vector<RR> m_rrs;
+
+};
+
+} /* namespace ndn */
+
+#endif /* RESPONSE_H_ */
diff --git a/src/rr.cpp b/src/rr.cpp
new file mode 100644
index 0000000..0b9d6d8
--- /dev/null
+++ b/src/rr.cpp
@@ -0,0 +1,79 @@
+/*
+ * RR.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "RR.h"
+
+namespace ndn {
+
+RR::RR()
+: id (0Lu)
+, m_rrData("ex.com")
+{
+ // TODO Auto-generated constructor stub
+
+}
+
+RR::~RR() {
+ // TODO Auto-generated destructor stub
+}
+
+template<bool T>
+size_t
+RR::wireEncode(EncodingImpl<T> & block) const
+{
+ size_t totalLength = 0;
+ string msg = this->getRrdata();
+ totalLength += prependByteArrayBlock(block,
+ tlv::ndns::RRData,
+ reinterpret_cast<const uint8_t*>(msg.c_str()),
+ msg.size()
+ );
+
+ return totalLength;
+}
+
+const Block&
+RR::wireEncode() const
+{
+ if (m_wire.hasWire())
+ return m_wire;
+ EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
+ EncodingBuffer buffer(estimatedSize, 0);
+ wireEncode(buffer);
+ m_wire = buffer.block();
+ return m_wire;
+}
+
+void
+RR::wireDecode(const Block& wire)
+{
+ if (!wire.hasWire()) {
+ throw Tlv::Error("The supplied block does not contain wire format");
+ }
+
+ if (wire.type() != tlv::ndns::RRData)
+ throw Tlv::Error("Unexpected TLV type when decoding Content");
+
+ m_wire = wire;
+ m_wire.parse();
+
+ Block::element_const_iterator it = m_wire.elements_begin();
+
+ if (it != m_wire.elements_end() && it->type() == tlv::ndns::RRData)
+ {
+ m_rrData = string(reinterpret_cast<const char*>(it->value()), it->value_size());
+ it ++;
+ } else {
+ throw Tlv::Error("not the RRData Type");
+ }
+
+}
+
+
+
+} /* namespace ndn */
diff --git a/src/rr.h b/src/rr.h
new file mode 100644
index 0000000..d6de294
--- /dev/null
+++ b/src/rr.h
@@ -0,0 +1,75 @@
+/*
+ * RR.h
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#ifndef RR_H_
+#define RR_H_
+
+#include <string>
+
+
+#include "ndns-tlv.h"
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/interest.hpp>
+
+
+using namespace std;
+
+namespace ndn {
+
+enum RRType
+{
+ NS,
+ TXT,
+ UNKNOWN
+};
+
+
+
+
+class RR {
+public:
+ RR();
+ virtual ~RR();
+
+ const string& getRrdata() const {
+ return m_rrData;
+ }
+
+ void setRrdata(const string& rrdata) {
+ this->m_rrData = rrdata;
+ }
+
+
+
+private:
+template<bool T>
+size_t
+wireEncode(EncodingImpl<T> & block) const;
+
+public:
+
+const Block&
+wireEncode() const;
+
+void
+wireDecode(const Block& wire);
+
+
+Interest
+toWire() const;
+
+
+private:
+ unsigned long id;
+ string m_rrData;
+
+ mutable Block m_wire;
+};
+
+} /* namespace ndn */
+
+#endif /* RR_H_ */
diff --git a/src/zone.cpp b/src/zone.cpp
new file mode 100644
index 0000000..9483941
--- /dev/null
+++ b/src/zone.cpp
@@ -0,0 +1,25 @@
+/*
+ * zone.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "zone.h"
+
+namespace ndn {
+
+Zone::Zone() {
+ // TODO Auto-generated constructor stub
+
+}
+
+Zone::~Zone() {
+ // TODO Auto-generated destructor stub
+}
+
+const RR Zone::hasName(string key) {
+ return "example.key";
+}
+
+} /* namespace ndn */
diff --git a/src/zone.h b/src/zone.h
new file mode 100644
index 0000000..bdc2581
--- /dev/null
+++ b/src/zone.h
@@ -0,0 +1,30 @@
+/*
+ * zone.h
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#ifndef ZONE_H_
+#define ZONE_H_
+
+#include <string>
+#include "rr.h"
+
+
+using namespace std;
+
+namespace ndn {
+
+class Zone {
+public:
+ Zone();
+ virtual ~Zone();
+
+ const RR hasName(string key);
+
+};
+
+} /* namespace ndn */
+
+#endif /* ZONE_H_ */
diff --git a/tests/NameServer_test.cpp b/tests/NameServer_test.cpp
new file mode 100644
index 0000000..92e8bcb
--- /dev/null
+++ b/tests/NameServer_test.cpp
@@ -0,0 +1,12 @@
+/*
+ * NameServer_test.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "tool/nameServer.h"
+
+namespace ndn {
+
+} /* namespace ndn */
diff --git a/tests/Query_test.cpp b/tests/Query_test.cpp
new file mode 100644
index 0000000..57feefb
--- /dev/null
+++ b/tests/Query_test.cpp
@@ -0,0 +1,12 @@
+/*
+ * query_test.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "src/query.h"
+
+namespace ndn {
+
+} /* namespace ndn */
diff --git a/tests/RR_test.cpp b/tests/RR_test.cpp
new file mode 100644
index 0000000..b14702d
--- /dev/null
+++ b/tests/RR_test.cpp
@@ -0,0 +1,24 @@
+/*
+ * RR_test.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "../src/RR.h"
+
+
+int
+main(int argc, char *argv[])
+{
+ ndn::RR rr;
+ rr.setRrdata("www2.ex.com");
+
+ ndn::Block block = rr.wireEncode();
+
+ ndn::RR rr2;
+ rr2.wireDecode(block);
+ cout<<rr.getRrdata()<<endl;
+
+ return 0;
+}//main
diff --git a/tests/Resolver_test.cpp b/tests/Resolver_test.cpp
new file mode 100644
index 0000000..7db3f1f
--- /dev/null
+++ b/tests/Resolver_test.cpp
@@ -0,0 +1,12 @@
+/*
+ * Resolver_test.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "resolver.h"
+
+namespace ndn {
+
+} /* namespace ndn */
diff --git a/tests/Zone_test.cpp b/tests/Zone_test.cpp
new file mode 100644
index 0000000..da5df01
--- /dev/null
+++ b/tests/Zone_test.cpp
@@ -0,0 +1,12 @@
+/*
+ * zone_test.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: shock
+ */
+
+#include "src/zone.h"
+
+namespace ndn {
+
+} /* namespace ndn */
diff --git a/tools/NameServer.cpp b/tools/NameServer.cpp
new file mode 100644
index 0000000..41e3397
--- /dev/null
+++ b/tools/NameServer.cpp
@@ -0,0 +1,188 @@
+/*
+ * NameServer.cpp
+ *
+ * Created on: 18 Jul, 2014
+ * Author: Xiaoke JIANG
+ *
+ */
+
+#include <boost/asio.hpp>
+#include <boost/noncopyable.hpp>
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+
+
+using namespace std;
+using namespace ndn;
+
+
+namespace ndn{
+class NameServer : boost::noncopyable
+{
+public:
+explicit
+NameServer(char *programName)
+: m_programName(programName)
+, m_hasError(false)
+, m_freshnessPeriod(time::milliseconds(1000))
+, m_face(m_ioService)
+{
+
+}//NameServer Construction
+
+
+void
+onInterest(const Name &name, const Interest &interest)
+{
+
+ cout<<"-> Interest: "<<name<<std::endl;
+
+}
+void
+onData(const ndn::Interest& interest, Data& data)
+{
+ Name dName = data.getName();
+ if (not m_name.isPrefixOf(dName) )
+ {
+ cout<<"!! ILLEGAL data: "<<dName<<", which does not starts with "<<m_name<<endl;
+ return;
+ }
+
+ cout<<"-> Data: "<<dName<<endl;
+
+ Name iName = interest.getName();
+ unsigned long seq = (unsigned long)iName.get(iName.size()-1).toNumber();
+
+
+ this->tryExpress();
+
+}
+void
+onTimeout(const ndn::Interest& interest)
+{
+ cout<<"!- Interest Timeout"<<interest.getName()<<endl;
+ Name iName = interest.getName();
+ unsigned long seq = (unsigned long)iName.get(iName.size()-1).toNumber();
+
+
+
+ this->tryExpress();
+}
+
+void
+onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
+{
+ std::cerr << "ERROR: Failed to register prefix in local hub's daemon" << std::endl;
+ std::cerr << "REASON: " << reason << std::endl;
+ m_hasError = true;
+ this->stop();
+}
+
+void
+DoExpress()
+{
+ Name name = this->m_name;
+
+
+ Selectors selector;
+ selector.setMustBeFresh(true);
+
+ Interest interest = Interest(name, selector, -1, this->m_freshnessPeriod, 1);
+
+ m_face.expressInterest(interest, boost::bind(&NameServer::onData, this, _1, _2),
+ boost::bind(&NameServer::onTimeout, this, _1));
+
+
+ //m_face.expressInterest(interest, boost::bind(&MyPing::OnData, this, _1, _2),
+ // boost::bind(&MyPing::OnTimeout, this, _1));
+}
+
+void
+tryExpress()
+{
+ this->DoExpress();
+}
+
+void
+singalHandler()
+{
+ cout<<"Fail to Register"<<endl;
+ this->stop();
+ exit(1);
+}
+
+void
+stop()
+{
+ cout<<"program "<<this->m_programName<<" stops"<<endl;
+ this->m_face.shutdown();
+ this->m_ioService.stop();
+}
+
+
+
+
+void
+run()
+{
+ std::cout << "\n=== NDNS Server for Zone " << m_prefix <<" starts===\n" << std::endl;
+
+ boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
+ signalSet.async_wait(bind(&NameServer::singalHandler, this));
+
+ m_name.set(m_prefix);
+
+ m_face.setInterestFilter(m_name,
+ bind(&NameServer::onInterest,
+ this, _1, _2),
+ bind(&NameServer::onRegisterFailed,
+ this, _1,_2));
+ try {
+ m_face.processEvents();
+ }
+ catch (std::exception& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ m_hasError = true;
+ m_ioService.stop();
+ }
+
+}
+
+ bool hasError() const {
+ return m_hasError;
+ }
+
+
+public:
+ KeyChain m_keyChain;
+ bool m_hasError;
+
+ time::milliseconds m_freshnessPeriod;
+ char* m_programName;
+ char* m_prefix;
+ Name m_name;
+ boost::asio::io_service m_ioService;
+ Face m_face;
+
+};//clcass NameServer
+}//namespace ndn
+
+
+int main(int argc, char * argv[])
+{
+ NameServer server;
+ server.run();
+
+ cout<<"the server ends with hasError="<<server.hasError()<<endl;
+
+ if (server.hasError()){
+ return 0;
+ } else {
+ return 1;
+ }
+
+}
+
diff --git a/tools/Resolver.cpp b/tools/Resolver.cpp
new file mode 100644
index 0000000..a64a184
--- /dev/null
+++ b/tools/Resolver.cpp
@@ -0,0 +1,229 @@
+/*
+ * myping.cc
+ *
+ * Created on: 21 Jun, 2014
+ * Author: shock
+ */
+
+#include <boost/noncopyable.hpp>
+#include <boost/asio.hpp>
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/selectors.hpp>
+
+#include <query.h>
+#include <rr.h>
+
+#include <unistd.h>
+#include <stdlib.h> //atoi
+
+
+
+#include <map>
+#include <vector>
+#include <sstream>
+
+//using std::cout;
+//using std::cin;
+//using std::cerr;
+//using std::endl;
+//using std::map;
+//using std::vector;
+//using std::exception;
+//using std::pair;
+//using std::string;
+
+using namespace std;
+
+namespace ndn{
+
+
+class Resolver : boost::noncopyable
+{
+
+ class RequestInfo
+ {
+ public:
+ RequestInfo(unsigned long seq)
+ : m_seq(seq)
+ {
+ }
+
+ void
+ SendInterest()
+ {
+ //m_sentT = time::system_clock::now();
+ }
+ void
+ GetData()
+ {
+ //this->m_receT = time::system_clock::now();
+ }
+
+ string
+ toString()
+ {
+ stringstream str;
+ str<<"m_seq="<<m_seq;
+ //s +="m_seq="+m_seq+" m_sentT="+" m_receT=";
+ return str.str();
+ }
+
+ public:
+ unsigned long m_seq;
+ time::milliseconds m_sentT;
+ time::milliseconds m_receT;
+ };
+
+public:
+Resolver(char *programName, char *scope, char *domain)
+: m_programName (programName)
+, m_authorityZone (scope)
+, m_rrLabel(domain)
+, m_interestLifetime (time::milliseconds(4000))
+, m_face (m_ioService)
+{
+ cout<<"Create "<<m_programName<<endl;
+}
+
+void
+onInterest(const Name &name, const Interest &interest)
+{
+
+ cout<<"-> Interest: "<<name<<std::endl;
+
+}
+void
+onData(const ndn::Interest& interest, Data& data)
+{
+ Response response(data);
+ response
+}
+void
+onTimeout(const ndn::Interest& interest)
+{
+ cout<<"!- Interest Timeout"<<interest.getName()<<endl;
+ Name iName = interest.getName();
+ unsigned long seq = (unsigned long)iName.get(iName.size()-1).toNumber();
+
+ this->tryExpress();
+
+
+}
+
+
+void
+doExpress(Interest interest)
+{
+ m_face.expressInterest(interest, boost::bind(&onData, this, _1, _2),
+ boost::bind(&onTimeout, this, _1));
+}
+
+void
+tryExpress()
+{
+
+ this->doExpress();
+
+}
+
+
+void
+singalHandler()
+{
+ this->stop();
+}
+
+void
+stop()
+{
+ cout<<"resolve stops"<<endl;
+ this->m_face.shutdown();
+ this->m_ioService.stop();
+}
+
+void
+run()
+{
+
+ boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
+ signalSet.async_wait(boost::bind(&singalHandler, this));
+
+ this->m_query.setAuthorityZone(this->m_authorityZone);
+ this->m_query.setRrLabel(this->m_rrLabel);
+ this->m_query.setRrType(RRType::NS);
+
+ Interest interest = m_query.toWire();
+ this->doExpress(interest);
+
+ try{
+ m_face.processEvents();
+ } catch (exception &e){
+ cerr<<"Error: "<<e.what()<<endl;
+ this->stop();
+ }
+
+}
+
+
+void
+resolve()
+{
+
+}
+
+
+private:
+ char *m_programName;
+ Name m_authorityZone;
+ Name m_rrLabel;
+ //Name m_name;
+ time::milliseconds m_interestLifetime;
+
+
+ Query m_query;
+
+ boost::asio::io_service m_ioService;
+ //This line MUST be before m_face declaration, or leads to segment error: 11
+
+ Face m_face;
+
+
+};//class MyPing
+
+}//namespace
+
+
+void
+usage()
+{
+ cout<<"-h to show the hint"<<endl;
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ if (argc < 2)
+ {
+ cout<<"You must have at least one parameter: resolve domain [scope]"<<endl;
+ return 0;
+ }
+
+
+ char * domain = argv[1];
+ char * scope;
+ if (argc == 3)
+ scope = argv[2];
+ else
+ scope = "/";
+
+
+ ndn::Resolver resolver(argv[0], scope, domain);
+ resolver.run();
+
+ return 0;
+}//main
+
+
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..e779031
--- /dev/null
+++ b/wscript
@@ -0,0 +1,23 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+VERSION='0.1'
+APPNAME="ndn-tlv-ping"
+
+def options(opt):
+ opt.load('compiler_cxx gnu_dirs')
+
+def configure(conf):
+ conf.load("compiler_cxx gnu_dirs")
+ conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'],
+ uselib_store='NDN_CXX', mandatory=True)
+
+def build (bld):
+
+ bld.program (
+ features = 'cxx',
+ target = 'rr-test',
+ source = 'tests/RR_test.cpp',
+ use = 'rr',
+ )
+ bld.stlib(source="src/rr.cpp", target="rr", use="NDN_CXX")
+
+