add constants definition

including enum, label and tlv

Change-Id: Ie4f780d9c65882ea80a73fc918c4b2387f4a9c01
diff --git a/docs/index.rst b/docs/index.rst
index 9c11ec6..de90ecc 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -15,7 +15,6 @@
    :maxdepth: 2
 
    INSTALL
-   ndns-packet-format
    ndns-db-manage
    manpages
 
diff --git a/docs/ndns-packet-format.rst b/docs/ndns-packet-format.rst
deleted file mode 100644
index d17a347..0000000
--- a/docs/ndns-packet-format.rst
+++ /dev/null
@@ -1,124 +0,0 @@
-.. _packetFormat:
-
-NDNS Packet format
-==================
-
-NDNS Query
-----------
-
-Requests to the zone are made in the format of a standard NDN interest.
-
-See `Interest section <http://named-data.net/doc/ndn-tlv/interest.html>`_ for details.
-
-
-NDNS Response
--------------
-
-NDNS Response is an ordinary `NDN-TLV Data packet <http://named-data.net/doc/ndn-tlv/data.html>`_
-with specialized ``MetaInfo`` block:
-
-::
-
-    Data ::= DATA-TLV TLV-LENGTH
-               Name
-               MetaInfo (= NdnsMetaInfo)
-               Content
-               Signature
-
-Every response from the NDNS system comes in the same generic form.
-Specialization of different types of NDNS responses is accomplished through
-``NDNS Type`` field of MetaInfo.
-
-See :ref `NDNS Type section` <NDNS-Type> for details
-
-
-NdnsMetaInfo
-~~~~~~~~~~~~
-
-``NdnsMetaInfo`` specified here represents portions that are specified in `MetaInfo
-<http://named-data.net/doc/ndn-tlv/data.html#metainfo>`_ of any NDN-TLV Data packet with
-NDNS specific additions.
-
-::
-
-    NdnsMetaInfo ::= META-INFO-TYPE TLV-LENGTH
-                       ContentType (= 0)
-                       FreshnessPeriod
-                       NdnsType
-                       AnswerCount
-
-
-ContentType
-+++++++++++
-
-::
-
-        ContentType ::= CONTENT-TYPE-TYPE TLV-LENGTH
-                          nonNegativeInteger
-
-For an NDNS packet the ``ContentType`` should always be ``BLOB`` (=0), specificity is accomplished
-by NDNS-Type.
-
-See :ref: `NDNS-Type` for details
-
-
-FreshnessPeriod
-+++++++++++++++
-
-::
-
-        FreshnessPeriod ::= FRESHNESS-PERIOD-TLV TLV-LENGTH
-                              nonNegativeInteger
-
-
-``FreshnessPeriod`` is required to be present in any NDNS response Data packets.  As in
-any other Data packet, it specifies how long after the arrive of the data the recieving
-node should wait before marking it stale.
-
-See `NDN Packet Specification - Freshness Period <http://named-data.net/doc/ndn-tlv/data.html#freshnessperiod>`_
-
-
-.. _NDNS-Type:
-
-NDNS-Type
-+++++++++
-
-::
-
-        NdnsType ::= NDNS-TYPE-TLV TLV-LENGTH
-                       nonNegativeIntegear
-
-There are 3 distinct types of NDNS Responses:
-
-+-----------+------------------------------------------------------------------+
-|    Type   | Description                                                      |
-+===========+==================================================================+
-| NDNS Data | indicates an answer was found, and that contains the requested   |
-|           | content                                                          |
-+-----------+------------------------------------------------------------------+
-| NDNS NACK | indicates that the responding zone has no content matching the   |
-|           | query.                                                           |
-+-----------+------------------------------------------------------------------+
-| NDNS AUTH | indicates that the zone has content, but a more specific         |
-|           | question is need to determine the correct content to server.     |
-+-----------+------------------------------------------------------------------+
-
-.. _AnswerCount:
-
-AnswerCount
-+++++++++++
-
-::
-
-            AnswerCount ::= ANSWER-COUNT-TLV TLV-LENGTH
-                    nonNegativeIntegear
-
-This field is used to specify the number of answer in a response.
-
-
-Content
-~~~~~~~
-
-::
-
-            Content ::= CONTENT-TYPE TLV-LENGTH BYTE*
diff --git a/src/ndns-enum.cpp b/src/ndns-enum.cpp
new file mode 100644
index 0000000..efc1bbf
--- /dev/null
+++ b/src/ndns-enum.cpp
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ndns-enum.hpp"
+
+namespace ndn {
+namespace ndns {
+
+std::string
+toString(NdnsType ndnsType)
+{
+  switch (ndnsType) {
+  case NDNS_RESP:
+    return "NDNS-Resp";
+  case NDNS_NACK:
+    return "NDNS-Nack";
+  case NDNS_AUTH:
+    return "NDNS-Auth";
+  case NDNS_NULL:
+    return "NDNS-Null";
+  default:
+    return "UNKNOWN";
+  }
+}
+
+} // namespace ndns
+} // namespace ndn
diff --git a/src/ndns-enum.hpp b/src/ndns-enum.hpp
new file mode 100644
index 0000000..c2bee36
--- /dev/null
+++ b/src/ndns-enum.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDNS_NDNS_ENUM_HPP
+#define NDNS_NDNS_ENUM_HPP
+
+#include <string>
+
+namespace ndn {
+namespace ndns {
+
+/**
+ * @brief NdnsType defined in Response.NdnsMetaInfo.NdnsType
+ */
+enum NdnsType {
+  NDNS_NULL = 0, ///< this is not a real type, just mean that MetaInfo does not contain NdnsType
+  NDNS_RESP = 1, ///< response type means there are requested RR
+  NDNS_NACK = 2, ///< no requested RR
+  NDNS_AUTH = 3, ///< only has RR for detailed (longer) label
+
+  NDNS_UNKNOWN = 255
+};
+
+/*
+ * @brief convert the ResponseType to String
+ */
+std::string
+toString(NdnsType ndnsType);
+
+} // namespace ndns
+} // namespace ndn
+
+#endif // NDNS_NDNS_ENUM_HPP
diff --git a/src/ndns-label.cpp b/src/ndns-label.cpp
new file mode 100644
index 0000000..6d0d1ae
--- /dev/null
+++ b/src/ndns-label.cpp
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ndns-label.hpp"
+#include <ndn-cxx/data.hpp>
+#include <ndn-cxx/interest.hpp>
+
+namespace ndn {
+namespace ndns {
+namespace label {
+
+inline size_t
+calculateSkip(const Name& name,
+              const Name& hint, const Name& zone)
+{
+  size_t skip = 0;
+
+  if (!hint.empty()) {
+    // These are only asserts. The caller should supply the right parameters
+    skip = hint.size() + 1 + zone.size();
+    BOOST_ASSERT(name.size() > skip);
+
+    BOOST_ASSERT(name.getPrefix(hint.size()) == hint);
+    BOOST_ASSERT(name.get(hint.size()) == ForwardingHintLabel);
+    BOOST_ASSERT(name.getSubName(hint.size() + 1, zone.size()) == zone);
+
+  }
+  else {
+    skip = zone.size();
+    BOOST_ASSERT(name.size() > skip);
+    BOOST_ASSERT(name.getPrefix(zone.size()) == zone);
+  }
+
+  BOOST_ASSERT(name.get(skip) == NdnsIterativeQuery ||
+               name.get(skip) == NdnsCertQuery);
+
+  ++skip;
+  return skip;
+}
+
+bool
+matchName(const Interest& interest,
+          const Name& hint, const Name& zone,
+          MatchResult& result)
+{
+  // [hint / FHLabel] / zoneName / <Update>|rrLabel / UPDATE|rrType
+
+  const Name& name = interest.getName();
+  size_t skip = calculateSkip(name, hint, zone);
+
+  if (name.size() - skip < 1)
+    return false;
+
+  result.rrType = name.get(-1);
+  result.rrLabel = name.getSubName(skip, std::max<size_t>(0, name.size() - skip - 1));
+  result.version = name::Component();
+
+  return true;
+}
+
+bool
+matchName(const Data& data,
+          const Name& hint, const Name& zone,
+          MatchResult& result)
+{
+  // [hint / FHLabel] / zoneName / <Update>|rrLabel / UPDATE|rrType
+
+  const Name& name = data.getName();
+  size_t skip = calculateSkip(name, hint, zone);
+
+  if (name.size() - skip < 2)
+    return false;
+
+  result.version = name.get(-1);
+  result.rrType = name.get(-2);
+  result.rrLabel = name.getSubName(skip, std::max<size_t>(0, name.size() - skip - 2));
+
+  return true;
+}
+
+} // namespace label
+} // namespace ndns
+} // namespace ndn
diff --git a/src/ndns-label.hpp b/src/ndns-label.hpp
new file mode 100644
index 0000000..accab00
--- /dev/null
+++ b/src/ndns-label.hpp
@@ -0,0 +1,123 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDNS_NDNS_LABEL_HPP
+#define NDNS_NDNS_LABEL_HPP
+
+#include "ndns-enum.hpp"
+
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/interest.hpp>
+
+#include <string>
+
+namespace ndn {
+namespace ndns {
+namespace label {
+
+/**
+ * @brief NDNS iterative query type
+ */
+
+const name::Component NdnsIterativeQuery("NDNS");
+
+/**
+ * @brief NDNS recursive query type
+ */
+const name::Component NdnsRecursiveQuery("NDNS-R");
+
+/**
+ * @brief NDNS ID-CERT query type
+ */
+const name::Component NdnsCertQuery("KEY");
+
+/////////////////////////////////////////////
+
+/**
+ * @brief label of forwarding hint
+ * @todo not support forwarding hint yet, for future use
+ */
+const name::Component ForwardingHintLabel("\xF0.");
+
+/**
+ * @brief label of update message, located at the last component in Interest name
+ */
+const name::Component NdnsUpdateLabel("UPDATE");
+
+//////////////////////////////////////////////
+
+/**
+ * @brief NS resource record type
+ */
+const name::Component NsRrType("NS");
+
+/**
+ * @brief ID-CERT resource record type
+ */
+const name::Component CertRrType("ID-CERT");
+
+//////////////////////////////////////////
+
+/**
+ * @brief result of Matching. version only works when matching a Interest Name
+ */
+struct MatchResult
+{
+  Name rrLabel;
+  name::Component rrType;
+  name::Component version;
+};
+
+/**
+ * @brief match the Interest (NDNS query, NDNS update) name
+ *
+ * @param[in] interest Interest to parse
+ * @param[in] hint Forwarding hint that is part of the Interest
+ *            (only the length will be taken into account)
+ * @param[in] zone Zone that the Interest is related to
+ *            (only the length will be taken into account)
+ * @param[out] result The matching result
+ * @return true if match succeeds, or false
+ */
+bool
+matchName(const Interest& interest,
+           const Name& hint, const Name& zone,
+           MatchResult& result);
+
+/**
+ * @brief match the Data (NDNS query response, NDNS update response) name
+ *
+ * @param[in] data Data to parse
+ * @param[in] hint Forwarding hint that is part of the Data
+ *            (only the length will be taken into account)
+ * @param[in] zone Zone that the Data is related to
+ *            (only the length will be taken into account)
+ * @param[out] result The matching result
+ * @return true if match succeeds, or false
+ */
+bool
+matchName(const Data& data,
+          const Name& hint, const Name& zone,
+          MatchResult& result);
+
+} // namespace label
+} // namespace ndns
+} // namespace ndn
+
+#endif // NDNS_NDNS_LABEL_HPP
diff --git a/src/ndns-tlv.hpp b/src/ndns-tlv.hpp
new file mode 100644
index 0000000..c81c1a6
--- /dev/null
+++ b/src/ndns-tlv.hpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NdnS authors and contributors.
+ *
+ * NdnS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NdnS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NdnS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDNS_NDNS_TLV_HPP
+#define NDNS_NDNS_TLV_HPP
+
+#include <ndn-cxx/encoding/tlv.hpp>
+
+namespace ndn {
+namespace ndns {
+namespace tlv {
+
+/**
+ * @brief the field defined in NDNS packet format
+ */
+enum {
+  NdnsType = 180, ///< Detailed Types are defined in NdnsType in ndns-enum.hpp
+  RrType = 190,
+  RrDataType = 191
+};
+
+} // namespace tlv
+} // namespace ndns
+} // namespace ndn
+
+#endif // NDNS_NDNS_TLV_HPP
diff --git a/tests/unit/ndns-enum.cpp b/tests/unit/ndns-enum.cpp
new file mode 100644
index 0000000..c396b6b
--- /dev/null
+++ b/tests/unit/ndns-enum.cpp
@@ -0,0 +1,45 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ndns-enum.hpp"
+#include "../boost-test.hpp"
+
+namespace ndn {
+namespace ndns {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NdnsEnum)
+
+BOOST_AUTO_TEST_CASE(NdnsTypeToString)
+{
+  BOOST_CHECK_EQUAL(toString(NDNS_RESP), "NDNS-Resp");
+  BOOST_CHECK_EQUAL(toString(NDNS_AUTH), "NDNS-Auth");
+  BOOST_CHECK_EQUAL(toString(NDNS_NACK), "NDNS-Nack");
+  BOOST_CHECK_EQUAL(toString(NDNS_NULL), "NDNS-Null");
+
+  BOOST_CHECK_EQUAL(toString(static_cast<NdnsType>(254)), "UNKNOWN");
+  BOOST_CHECK_EQUAL(toString(static_cast<NdnsType>(255)), "UNKNOWN");
+  BOOST_CHECK_EQUAL(toString(static_cast<NdnsType>(256)), "UNKNOWN");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndns
+} // namespace ndn
diff --git a/tests/unit/ndns-label.cpp b/tests/unit/ndns-label.cpp
new file mode 100644
index 0000000..cb2e47e
--- /dev/null
+++ b/tests/unit/ndns-label.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ndns-label.hpp"
+#include "../boost-test.hpp"
+
+namespace ndn {
+namespace ndns {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NdnsLabel)
+
+BOOST_AUTO_TEST_CASE(MatchInterest)
+{
+  using namespace label;
+  Name hint("/att");
+  Name zone("/net/ndnsim");
+
+  Interest interest1("/att/%F0./net/ndnsim/NDNS/www/dsk-111/NS");
+  Interest interest2("/att/%F0./net/ndnsim/NDNS/www/dsk-111/NS/%FD%00");
+
+  MatchResult re;
+  BOOST_CHECK_EQUAL(matchName(interest1, hint, zone, re), true);
+  BOOST_CHECK_EQUAL(re.rrLabel, Name("/www/dsk-111"));
+  BOOST_CHECK_EQUAL(re.rrType, name::Component("NS"));
+  BOOST_CHECK_EQUAL(re.version, name::Component());
+
+  BOOST_CHECK_EQUAL(matchName(interest2, hint, zone, re), true);
+  BOOST_CHECK_EQUAL(re.rrLabel, Name("/www/dsk-111/NS"));
+  BOOST_CHECK_EQUAL(re.rrType, name::Component::fromEscapedString("%FD%00"));
+  BOOST_CHECK_EQUAL(re.version, name::Component());
+}
+
+BOOST_AUTO_TEST_CASE(MatchData)
+{
+  using namespace label;
+  Name hint("/att");
+  Name zone("/net/ndnsim");
+
+  Data data1("/att/%F0./net/ndnsim/NDNS/www/dsk-111/NS/%FD%00");
+  Data data2("/att/%F0./net/ndnsim/NDNS/www/dsk-111/NS");
+
+  MatchResult re;
+  BOOST_CHECK_EQUAL(matchName(data1, hint, zone, re), true);
+  BOOST_CHECK_EQUAL(re.rrLabel, Name("/www/dsk-111"));
+  BOOST_CHECK_EQUAL(re.rrType, name::Component("NS"));
+  BOOST_REQUIRE_NO_THROW(re.version.toVersion());
+  BOOST_CHECK_EQUAL(re.version.toVersion(), 0);
+
+  BOOST_CHECK_EQUAL(matchName(data2, hint, zone, re), true);
+  BOOST_CHECK_EQUAL(re.rrLabel, Name("/www"));
+  BOOST_CHECK_EQUAL(re.rrType, name::Component("dsk-111"));
+  BOOST_REQUIRE_THROW(re.version.toVersion(), ndn::tlv::Error);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndns
+} // namespace ndn