summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/rdata/generic
diff options
context:
space:
mode:
authorJelte Jansen <jelte@isc.org>2013-01-10 09:56:52 +0100
committerJelte Jansen <jelte@isc.org>2013-01-10 12:35:11 +0100
commit82a1d5c34e951687d67a6313fb42d9e75768adbc (patch)
tree8151aecaebe177a8ec43f4a2e8f5d623432d7c04 /src/lib/dns/rdata/generic
parent[2498] Update HINFO and NAPTR to use new createFromText (diff)
downloadkea-82a1d5c34e951687d67a6313fb42d9e75768adbc.tar.xz
kea-82a1d5c34e951687d67a6313fb42d9e75768adbc.zip
[2498] move out some common charstrings functions
And add a number of tests
Diffstat (limited to 'src/lib/dns/rdata/generic')
-rw-r--r--src/lib/dns/rdata/generic/detail/char_string.cc46
-rw-r--r--src/lib/dns/rdata/generic/detail/char_string.h33
-rw-r--r--src/lib/dns/rdata/generic/hinfo_13.cc69
-rw-r--r--src/lib/dns/rdata/generic/naptr_35.cc30
4 files changed, 98 insertions, 80 deletions
diff --git a/src/lib/dns/rdata/generic/detail/char_string.cc b/src/lib/dns/rdata/generic/detail/char_string.cc
index e2857b37f4..de4fb0f108 100644
--- a/src/lib/dns/rdata/generic/detail/char_string.cc
+++ b/src/lib/dns/rdata/generic/detail/char_string.cc
@@ -14,9 +14,11 @@
#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
#include <dns/rdata.h>
#include <dns/master_lexer.h>
#include <dns/rdata/generic/detail/char_string.h>
+#include <util/buffer.h>
#include <boost/lexical_cast.hpp>
@@ -114,6 +116,50 @@ charStringToString(const CharString& char_string) {
return (s);
}
+int compareCharStrings(const detail::CharString& self,
+ const detail::CharString& other) {
+ const size_t self_len = self[0];
+ const size_t other_len = other[0];
+ const size_t cmp_len = std::min(self_len, other_len);
+ const int cmp = memcmp(&self[1], &other[1], cmp_len);
+ if (cmp < 0) {
+ return (-1);
+ } else if (cmp > 0) {
+ return (1);
+ } else if (self_len < other_len) {
+ return (-1);
+ } else if (self_len > other_len) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+size_t
+bufferToCharString(isc::util::InputBuffer& buffer, size_t rdata_len,
+ CharString& target) {
+ if (rdata_len < 1 || buffer.getLength() < 1) {
+ isc_throw(isc::dns::DNSMessageFORMERR,
+ "insufficient data to read character-string length");
+ }
+ const uint8_t len = buffer.readUint8();
+ if (rdata_len < len + 1) {
+ isc_throw(isc::dns::DNSMessageFORMERR,
+ "character string length is too large: " <<
+ static_cast<int>(len));
+ }
+ if (buffer.getLength() < len) {
+ isc_throw(isc::dns::DNSMessageFORMERR,
+ "not enough data in buffer to read character-string");
+ }
+
+ target.resize(len + 1);
+ target[0] = len;
+ buffer.readData(&target[0] + 1, len);
+
+ return (len + 1);
+}
+
} // end of detail
} // end of generic
} // end of rdata
diff --git a/src/lib/dns/rdata/generic/detail/char_string.h b/src/lib/dns/rdata/generic/detail/char_string.h
index 4a146db2ae..0b5bf0d59d 100644
--- a/src/lib/dns/rdata/generic/detail/char_string.h
+++ b/src/lib/dns/rdata/generic/detail/char_string.h
@@ -19,6 +19,7 @@
#include <string>
#include <vector>
+#include <algorithm>
#include <stdint.h>
namespace isc {
@@ -66,6 +67,38 @@ void stringToCharString(const MasterToken::StringRegion& str_region,
/// \return A string representation of \c char_string.
std::string charStringToString(const CharString& char_string);
+/// \brief Compare two CharString objects
+///
+/// \param self The CharString field to compare
+/// \param other The CharString field to compare to
+///
+/// \return -1 if \c self would be sorted before \c other
+/// 1 if \c self would be sorted after \c other
+/// 0 if \c self and \c other are equal
+int compareCharStrings(const CharString& self, const CharString& other);
+
+/// \brief Convert a buffer containing a character-string to CharString
+///
+/// This method reads one character-string from the given buffer (in wire
+/// format) and places the result in the given \c CharString object.
+/// Since this is expected to be used in message parsing, the exception it
+/// raises is of that type.
+///
+/// On success, the buffer position is advanced to the end of the char-string,
+/// and the number of bytes read is returned.
+///
+/// \param buffer The buffer to read from.
+/// \param rdata_len The total size of the rr's rdata currently being read
+/// (used for integrity checks in the wire data)
+/// \param target The \c CharString where the result will be stored. Any
+/// existing data in the target will be overwritten.
+/// \throw DNSMessageFormERR If the available data is not enough to read
+/// the character-string, or if the character-string length is out of bounds
+/// \return The number of bytes read
+size_t bufferToCharString(isc::util::InputBuffer& buffer, size_t rdata_len,
+ CharString& target);
+
+
} // namespace detail
} // namespace generic
} // namespace rdata
diff --git a/src/lib/dns/rdata/generic/hinfo_13.cc b/src/lib/dns/rdata/generic/hinfo_13.cc
index bae435e3b1..9f678dd9ad 100644
--- a/src/lib/dns/rdata/generic/hinfo_13.cc
+++ b/src/lib/dns/rdata/generic/hinfo_13.cc
@@ -35,67 +35,6 @@ using namespace isc::dns;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
-// helper(s)
-namespace {
-
-/// \brief Reads one text field from the given buffer into the given CharString
-///
-/// \return The number of bytes read
-size_t
-readTextField(detail::CharString& target, InputBuffer& buffer,
- size_t rdata_len) {
- if (rdata_len < 1 || buffer.getLength() < 1) {
- isc_throw(isc::dns::DNSMessageFORMERR, "Error in parsing "
- "HINFO RDATA: insufficient data");
- }
- const uint8_t len = buffer.readUint8();
- if (rdata_len < len + 1) {
- isc_throw(isc::dns::DNSMessageFORMERR, "Error in parsing "
- "HINFO RDATA: character string length is too large: " <<
- static_cast<int>(len));
- }
- if (buffer.getLength() < len) {
- isc_throw(isc::dns::DNSMessageFORMERR, "Error in parsing "
- "HINFO RDATA: not enough data in buffer to read: " <<
- static_cast<int>(len) << " bytes");
- }
-
- target.resize(len + 1);
- target[0] = len;
- buffer.readData(&target[0] + 1, len);
-
- return (len + 1);
-}
-
-/// \brief Compare one CharString field to another
-///
-/// \param self The CharString field to compare
-/// \param other The CharString field to compare to
-///
-/// \return -1 if \c self would be sorted before \c other
-/// 1 if \c self would be sorted after \c other
-/// 0 if \c self and \c other are equal
-int compareField(const detail::CharString& self,
- const detail::CharString& other) {
- const size_t self_len = self[0];
- const size_t other_len = other[0];
- const size_t cmp_len = min(self_len, other_len);
- const int cmp = memcmp(&self[1], &other[1], cmp_len);
- if (cmp < 0) {
- return (-1);
- } else if (cmp > 0) {
- return (1);
- } else if (self_len < other_len) {
- return (-1);
- } else if (self_len > other_len) {
- return (1);
- } else {
- return (0);
- }
-}
-
-} // end unnamed namespace
-
class HINFOImpl {
public:
HINFOImpl(const std::string& hinfo_str) {
@@ -118,8 +57,8 @@ public:
}
HINFOImpl(InputBuffer& buffer, size_t rdata_len) {
- rdata_len -= readTextField(cpu, buffer, rdata_len);
- rdata_len -= readTextField(os, buffer, rdata_len);
+ rdata_len -= detail::bufferToCharString(buffer, rdata_len, cpu);
+ rdata_len -= detail::bufferToCharString(buffer, rdata_len, os);
if (rdata_len != 0) {
isc_throw(isc::dns::DNSMessageFORMERR, "Error in parsing " <<
"HINFO RDATA: bytes left at end: " <<
@@ -193,11 +132,11 @@ int
HINFO::compare(const Rdata& other) const {
const HINFO& other_hinfo = dynamic_cast<const HINFO&>(other);
- const int cmp = compareField(impl_->cpu, other_hinfo.impl_->cpu);
+ const int cmp = compareCharStrings(impl_->cpu, other_hinfo.impl_->cpu);
if (cmp != 0) {
return (cmp);
}
- return (compareField(impl_->os, other_hinfo.impl_->os));
+ return (compareCharStrings(impl_->os, other_hinfo.impl_->os));
}
const std::string
diff --git a/src/lib/dns/rdata/generic/naptr_35.cc b/src/lib/dns/rdata/generic/naptr_35.cc
index 611fc5b16d..4d891e6a6c 100644
--- a/src/lib/dns/rdata/generic/naptr_35.cc
+++ b/src/lib/dns/rdata/generic/naptr_35.cc
@@ -45,9 +45,9 @@ public:
preference = buffer.readUint16();
rdata_len -= 4;
- rdata_len -= readTextField(flags, buffer, rdata_len);
- rdata_len -= readTextField(services, buffer, rdata_len);
- rdata_len -= readTextField(regexp, buffer, rdata_len);
+ rdata_len -= detail::bufferToCharString(buffer, rdata_len, flags);
+ rdata_len -= detail::bufferToCharString(buffer, rdata_len, services);
+ rdata_len -= detail::bufferToCharString(buffer, rdata_len, regexp);
replacement = Name(buffer);
if (rdata_len < 1) {
isc_throw(isc::dns::DNSMessageFORMERR, "Error in parsing "
@@ -192,22 +192,22 @@ NAPTR::compare(const Rdata& other) const {
return (1);
}
- if (impl_->flags < other_naptr.impl_->flags) {
- return (-1);
- } else if (impl_->flags > other_naptr.impl_->flags) {
- return (1);
+ const int fcmp = detail::compareCharStrings(impl_->flags,
+ other_naptr.impl_->flags);
+ if (fcmp != 0) {
+ return (fcmp);
}
- if (impl_->services < other_naptr.impl_->services) {
- return (-1);
- } else if (impl_->services > other_naptr.impl_->services) {
- return (1);
+ const int scmp = detail::compareCharStrings(impl_->services,
+ other_naptr.impl_->services);
+ if (scmp != 0) {
+ return (scmp);
}
- if (impl_->regexp < other_naptr.impl_->regexp) {
- return (-1);
- } else if (impl_->regexp > other_naptr.impl_->regexp) {
- return (1);
+ const int rcmp = detail::compareCharStrings(impl_->regexp,
+ other_naptr.impl_->regexp);
+ if (rcmp != 0) {
+ return (rcmp);
}
return (compareNames(impl_->replacement, other_naptr.impl_->replacement));