Browse Source

[1602] initial implementation

Jelte Jansen 13 years ago
parent
commit
0255bfb992

+ 2 - 0
src/lib/dns/Makefile.am

@@ -91,6 +91,7 @@ libdns___la_LDFLAGS = -no-undefined -version-info 1:0:1
 libdns___la_SOURCES =
 libdns___la_SOURCES =
 libdns___la_SOURCES += edns.h edns.cc
 libdns___la_SOURCES += edns.h edns.cc
 libdns___la_SOURCES += exceptions.h exceptions.cc
 libdns___la_SOURCES += exceptions.h exceptions.cc
+libdns___la_SOURCES += labelsequence.h labelsequence.cc
 libdns___la_SOURCES += masterload.h masterload.cc
 libdns___la_SOURCES += masterload.h masterload.cc
 libdns___la_SOURCES += message.h message.cc
 libdns___la_SOURCES += message.h message.cc
 libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
 libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
@@ -140,6 +141,7 @@ libdns___includedir = $(includedir)/dns
 libdns___include_HEADERS = \
 libdns___include_HEADERS = \
 	edns.h \
 	edns.h \
 	exceptions.h \
 	exceptions.h \
+	labelsequence.h \
 	message.h \
 	message.h \
 	messagerenderer.h \
 	messagerenderer.h \
 	name.h \
 	name.h \

+ 92 - 0
src/lib/dns/labelsequence.cc

@@ -0,0 +1,92 @@
+// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dns/labelsequence.h>
+#include <exceptions/exceptions.h>
+
+// TODO: REMOVE
+#include <iostream>
+
+namespace isc {
+namespace dns {
+
+
+LabelSequence::LabelSequence(const Name& name) : name_(name),
+                             first_label_(0) {
+    isc::util::OutputBuffer buf(0);
+    name.toWire(buf);
+    size_t buflen = buf.getLength();
+    data_ = new char[buflen];
+    memcpy(data_, buf.getData(), buflen);
+    data_[buflen-1] = '\0';
+
+    size_t label_count_ = name.getLabelCount();
+    last_label_ = label_count_ - 1;
+    offsets_ = new size_t[label_count_];
+    offsets_[0] = 0;
+    for (size_t i = 1; i < label_count_; ++i) {
+        offsets_[i] = offsets_[i - 1] + data_[offsets_[i - 1]] + 1;
+    }
+}
+
+LabelSequence::~LabelSequence() {
+    delete[] data_;
+    delete[] offsets_;
+}
+
+const char*
+LabelSequence::getData() const {
+    return &data_[offsets_[first_label_]];
+}
+
+const char*
+LabelSequence::getData(size_t *len) const {
+    std::cout << "[XX]" << std::endl;
+    std::cout << "[XX] at: " << offsets_[first_label_] << std::endl;
+    std::cout << "[XX] value: " << name_.at(offsets_[first_label_]) << std::endl;
+    std::cout << "[XX] ptr: " << name_.at_p(offsets_[first_label_]) << std::endl;
+    *len = offsets_[last_label_] - offsets_[first_label_];
+    return name_.at_p(offsets_[first_label_]);
+}
+
+bool
+LabelSequence::equals(const LabelSequence& other, bool case_sensitive) const {
+    if (case_sensitive) {
+        return (strcasecmp(getData(), other.getData()) == 0);
+    } else {
+        return (strcmp(getData(), other.getData()) == 0);
+    }
+}
+
+void
+LabelSequence::split(int i) {
+    if (i > 0) {
+        if (first_label_ + i > last_label_) {
+            isc_throw(Exception, "split(" << i <<") but labelcount: " << getLabelCount());
+        } else {
+            first_label_ += i;
+        }
+    } else if (i < 0) {
+        if (last_label_ + i < first_label_) {
+            isc_throw(Exception, "split(" << i <<") but labelcount: " << getLabelCount());
+        } else {
+            last_label_ += i;
+            data_[offsets_[last_label_]] = '\0';
+        }
+    }
+}
+
+} // end namespace dns
+} // end namespace isc
+

+ 50 - 0
src/lib/dns/labelsequence.h

@@ -0,0 +1,50 @@
+// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LABELSEQUENCE_H
+#define __LABELSEQUENCE_H 1
+
+#include <dns/name.h>
+#include <util/buffer.h>
+
+namespace isc {
+namespace dns {
+
+class LabelSequence {
+public:
+    LabelSequence(const Name& name);
+    ~LabelSequence();
+
+    const char* getData() const;
+    const char* getData(size_t* len) const;
+
+    bool equals(const LabelSequence& other, bool case_sensitive = false) const;
+
+    void split(int i);
+
+    size_t getLabelCount() { return last_label_ - first_label_ + 1; }
+
+private:
+    const Name& name_;
+    size_t first_label_;
+    size_t last_label_;
+    char* data_;
+    size_t* offsets_;
+};
+
+
+} // end namespace dns
+} // end namespace isc
+
+#endif

+ 9 - 0
src/lib/dns/name.h

@@ -298,6 +298,15 @@ public:
         }
         }
         return (ndata_[pos]);
         return (ndata_[pos]);
     }
     }
+
+    const char* at_p(size_t pos) const
+    {
+        if (pos >= length_) {
+            isc_throw(OutOfRange, "Out of range access in Name::at()");
+        }
+        return (&ndata_[pos]);
+    }
+
     /// \brief Gets the length of the <code>Name</code> in its wire format.
     /// \brief Gets the length of the <code>Name</code> in its wire format.
     ///
     ///
     /// This method never throws an exception.
     /// This method never throws an exception.

+ 1 - 0
src/lib/dns/tests/Makefile.am

@@ -19,6 +19,7 @@ if HAVE_GTEST
 TESTS += run_unittests
 TESTS += run_unittests
 run_unittests_SOURCES = unittest_util.h unittest_util.cc
 run_unittests_SOURCES = unittest_util.h unittest_util.cc
 run_unittests_SOURCES += edns_unittest.cc
 run_unittests_SOURCES += edns_unittest.cc
+run_unittests_SOURCES += labelsequence_unittest.cc
 run_unittests_SOURCES += messagerenderer_unittest.cc
 run_unittests_SOURCES += messagerenderer_unittest.cc
 run_unittests_SOURCES += name_unittest.cc
 run_unittests_SOURCES += name_unittest.cc
 run_unittests_SOURCES += nsec3hash_unittest.cc
 run_unittests_SOURCES += nsec3hash_unittest.cc

+ 171 - 0
src/lib/dns/tests/labelsequence_unittest.cc

@@ -0,0 +1,171 @@
+// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dns/labelsequence.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::dns;
+
+class LabelSequenceTest : public ::testing::Test {
+public:
+    LabelSequenceTest() : ls1(Name("example.org")),
+                          ls2(Name("example.com")),
+                          ls3(Name("example.org")),
+                          ls4(Name("foo.bar")),
+                          ls5(Name("example.ORG")),
+                          ls6(Name("ExAmPlE.org")),
+                          ls7(Name("."))
+    {};
+
+    LabelSequence ls1;
+    LabelSequence ls2;
+    LabelSequence ls3;
+    LabelSequence ls4;
+    LabelSequence ls5;
+    LabelSequence ls6;
+    LabelSequence ls7;
+};
+
+// Basic equality tests
+TEST_F(LabelSequenceTest, equals_sensitive) {
+    EXPECT_TRUE(ls1.equals(ls1));
+    EXPECT_FALSE(ls1.equals(ls2));
+    EXPECT_TRUE(ls1.equals(ls3));
+    EXPECT_FALSE(ls1.equals(ls4));
+    EXPECT_FALSE(ls1.equals(ls5));
+    EXPECT_FALSE(ls1.equals(ls6));
+    EXPECT_FALSE(ls1.equals(ls7));
+
+    EXPECT_FALSE(ls2.equals(ls1));
+    EXPECT_TRUE(ls2.equals(ls2));
+    EXPECT_FALSE(ls2.equals(ls3));
+    EXPECT_FALSE(ls2.equals(ls4));
+    EXPECT_FALSE(ls2.equals(ls5));
+    EXPECT_FALSE(ls2.equals(ls6));
+    EXPECT_FALSE(ls2.equals(ls7));
+
+    EXPECT_TRUE(ls3.equals(ls1));
+    EXPECT_FALSE(ls3.equals(ls2));
+    EXPECT_TRUE(ls3.equals(ls3));
+    EXPECT_FALSE(ls3.equals(ls4));
+    EXPECT_FALSE(ls3.equals(ls5));
+    EXPECT_FALSE(ls3.equals(ls6));
+    EXPECT_FALSE(ls3.equals(ls7));
+
+    EXPECT_FALSE(ls4.equals(ls1));
+    EXPECT_FALSE(ls4.equals(ls2));
+    EXPECT_FALSE(ls4.equals(ls3));
+    EXPECT_TRUE(ls4.equals(ls4));
+    EXPECT_FALSE(ls4.equals(ls5));
+    EXPECT_FALSE(ls4.equals(ls6));
+    EXPECT_FALSE(ls4.equals(ls7));
+}
+
+TEST_F(LabelSequenceTest, equals_insensitive) {
+    EXPECT_TRUE(ls1.equals(ls1, true));
+    EXPECT_FALSE(ls1.equals(ls2, true));
+    EXPECT_TRUE(ls1.equals(ls3, true));
+    EXPECT_FALSE(ls1.equals(ls4, true));
+    EXPECT_TRUE(ls1.equals(ls5, true));
+    EXPECT_TRUE(ls1.equals(ls6, true));
+    EXPECT_FALSE(ls1.equals(ls7, true));
+
+    EXPECT_FALSE(ls2.equals(ls1, true));
+    EXPECT_TRUE(ls2.equals(ls2, true));
+    EXPECT_FALSE(ls2.equals(ls3, true));
+    EXPECT_FALSE(ls2.equals(ls4, true));
+    EXPECT_FALSE(ls2.equals(ls5, true));
+    EXPECT_FALSE(ls2.equals(ls6, true));
+    EXPECT_FALSE(ls2.equals(ls7, true));
+
+    EXPECT_TRUE(ls3.equals(ls1, true));
+    EXPECT_FALSE(ls3.equals(ls2, true));
+    EXPECT_TRUE(ls3.equals(ls3, true));
+    EXPECT_FALSE(ls3.equals(ls4, true));
+    EXPECT_TRUE(ls3.equals(ls5, true));
+    EXPECT_TRUE(ls3.equals(ls6, true));
+    EXPECT_FALSE(ls3.equals(ls7, true));
+
+    EXPECT_FALSE(ls4.equals(ls1, true));
+    EXPECT_FALSE(ls4.equals(ls2, true));
+    EXPECT_FALSE(ls4.equals(ls3, true));
+    EXPECT_TRUE(ls4.equals(ls4, true));
+    EXPECT_FALSE(ls4.equals(ls5, true));
+    EXPECT_FALSE(ls4.equals(ls6, true));
+    EXPECT_FALSE(ls4.equals(ls7, true));
+}
+
+
+TEST_F(LabelSequenceTest, getData) {
+    EXPECT_STREQ("\007example\003org\0", ls1.getData());
+    EXPECT_STREQ("\007example\003com\0", ls2.getData());
+    EXPECT_STREQ("\007example\003org\0", ls3.getData());
+    EXPECT_STREQ("\003foo\003bar\0", ls4.getData());
+    EXPECT_STREQ("\007example\003ORG\0", ls5.getData());
+    EXPECT_STREQ("\007ExAmPlE\003org\0", ls6.getData());
+    EXPECT_STREQ("\0", ls7.getData());
+};
+
+TEST_F(LabelSequenceTest, split_pos) {
+    ls1.split(0);
+    EXPECT_STREQ("\007example\003org\0", ls1.getData());
+    ls1.split(1);
+    EXPECT_STREQ("\003org\0", ls1.getData());
+    ls1.split(1);
+    EXPECT_STREQ("\0", ls1.getData());
+    EXPECT_TRUE(ls1.equals(ls7));
+
+    ls2.split(2);
+    EXPECT_STREQ("\0", ls2.getData());
+    EXPECT_TRUE(ls2.equals(ls7));
+}
+
+TEST_F(LabelSequenceTest, split_neg) {
+    ls1.split(0);
+    EXPECT_STREQ("\007example\003org\0", ls1.getData());
+    ls1.split(-1);
+    EXPECT_STREQ("\007example\0", ls1.getData());
+    ls1.split(-1);
+    EXPECT_STREQ("\0", ls1.getData());
+    EXPECT_TRUE(ls1.equals(ls7));
+
+    ls2.split(-2);
+    EXPECT_STREQ("\0", ls2.getData());
+    EXPECT_TRUE(ls2.equals(ls7));
+}
+
+TEST_F(LabelSequenceTest, getLabelCount) {
+    EXPECT_EQ(3, ls1.getLabelCount());
+    ls1.split(0);
+    EXPECT_EQ(3, ls1.getLabelCount());
+    ls1.split(1);
+    EXPECT_EQ(2, ls1.getLabelCount());
+    ls1.split(1);
+    EXPECT_EQ(1, ls1.getLabelCount());
+
+    EXPECT_EQ(3, ls2.getLabelCount());
+    ls2.split(2);
+    EXPECT_EQ(1, ls2.getLabelCount());
+
+    EXPECT_EQ(3, ls3.getLabelCount());
+    ls3.split(-1);
+    EXPECT_EQ(2, ls3.getLabelCount());
+    ls3.split(-1);
+    EXPECT_EQ(1, ls3.getLabelCount());
+
+    EXPECT_EQ(3, ls4.getLabelCount());
+    ls4.split(-2);
+    EXPECT_EQ(1, ls4.getLabelCount());
+}