Commit 7a310b66 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

supported TXT RR (partially) so that we can implement authors.bind:-)


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/f2f200910@172 e5f2f494-b856-4b98-b285-d166d9295462
parent b5ac8153
......@@ -46,6 +46,7 @@ class DNSNoMessageParser : public DNSException {};
class DNSInvalidMessageSection : public DNSException {};
class DNSInvalidRendererPosition : public DNSException {};
class DNSMessageTooShort : public DNSException {};
class DNSCharStringTooLong : public DNSException {};
}
}
#endif // __EXCEPTIONS_HH
......
......@@ -307,11 +307,11 @@ Message::addRR(section_t section, const RR& rr)
std::bind2nd(MatchRR(), rr));
if (it != sections_[section].end()) {
(*it)->setTtl(std::min((*it)->getTtl(), rr.getTtl()));
(*it)->addRdata(Rdata::RDATAPTR(rr.getRdata()->copy()));
(*it)->addRdata(Rdata::RdataPtr(rr.getRdata()->copy()));
} else {
RRset *rrset = new RRset(rr.getName(), rr.getClass(), rr.getType(),
rr.getTtl());
rrset->addRdata(Rdata::RDATAPTR(rr.getRdata()->copy()));
rrset->addRdata(Rdata::RdataPtr(rr.getRdata()->copy()));
sections_[section].push_back(RRsetPtr(rrset));
}
}
......
......@@ -36,6 +36,7 @@ using isc::dns::TTL;
using isc::dns::Rdata::IN::A;
using isc::dns::Rdata::IN::AAAA;
using isc::dns::Rdata::Generic::NS;
using isc::dns::Rdata::Generic::TXT;
using isc::dns::RRset;
using isc::dns::Rdata::Rdata;
using isc::dns::Question;
......@@ -81,6 +82,8 @@ RRType::RRType(const std::string& typestr)
typeval_ = 1;
else if (typestr == "NS")
typeval_ = 2;
else if (typestr == "TXT")
typeval_ = 16;
else if (typestr == "AAAA")
typeval_ = 28;
else
......@@ -94,6 +97,8 @@ RRType::toText() const
return ("A");
else if (typeval_ == 2)
return ("NS");
else if (typeval_ == 16)
return ("TXT");
else if (typeval_ == 28)
return ("AAAA");
throw std::runtime_error("unexpected type");
......@@ -107,6 +112,7 @@ RRType::toWire(Buffer& buffer) const
const RRType RRType::A("A");
const RRType RRType::NS("NS");
const RRType RRType::TXT("TXT");
const RRType RRType::AAAA("AAAA");
// ...more to follow
......@@ -147,6 +153,12 @@ createNSDataFromText(const std::string& text_rdata)
return (new NS(text_rdata));
}
Rdata *
createTXTDataFromText(const std::string& text_rdata)
{
return (new TXT(text_rdata));
}
RdataFactoryRegister::RdataFactoryRegister()
{
rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
......@@ -155,11 +167,17 @@ RdataFactoryRegister::RdataFactoryRegister()
rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
(RRClassTypePair(RRClass::IN, RRType::AAAA),
createAAAADataFromText));
//XXX: NS belongs to the 'generic' class. should revisit it.
//XXX: NS/TXT belongs to the 'generic' class. should revisit it.
rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
(RRClassTypePair(RRClass::IN, RRType::NS),
createNSDataFromText));
}
rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
(RRClassTypePair(RRClass::IN, RRType::TXT),
createTXTDataFromText));
// XXX: we should treat class-agnostic type accordingly.
rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
(RRClassTypePair(RRClass::CH, RRType::TXT),
createTXTDataFromText));}
Rdata *
Rdata::fromText(const RRClass& rrclass, const RRType& rrtype,
......@@ -273,6 +291,90 @@ NS::copy() const
return (new NS(toText()));
}
TXT::TXT(const std::string& text_data)
{
size_t length = text_data.size();
size_t pos_begin = 0;
if (length > 1 && text_data[0] == '"' && text_data[length - 1] == '"') {
pos_begin = 1;
length -= 2;
}
if (text_data.size() > MAX_CHARACTER_STRING)
throw DNSCharStringTooLong();
string_list.push_back(text_data.substr(pos_begin, length));
}
bool
TXT::operator==(const TXT& other) const
{
std::vector<std::string>::const_iterator lit, rit;
if (count() != other.count())
return (false);
lit = string_list.begin();
rit = other.string_list.begin();
while (lit != string_list.end()) {
if (*lit != *rit)
return (false);
++lit;
++rit;
}
return (true);
}
void
TXT::fromWire(Buffer& buffer, NameDecompressor& decompressor)
{
//TBD
}
void
TXT::toWire(Buffer& buffer, NameCompressor& compressor) const
{
std::vector<std::string>::const_iterator it;
size_t total_length = 0;
size_t length_pos;
length_pos = buffer.getSize();
buffer.writeUint16(0); // dummy data. filled in later
for (it = string_list.begin(); it != string_list.end(); ++it) {
buffer.writeUint8((*it).size());
buffer.writeData((*it).c_str(), (*it).size());
total_length += (*it).size() + 1;
}
buffer.writeUint16At(total_length, length_pos);
}
std::string
TXT::toText() const
{
std::vector<std::string>::const_iterator it;
std::string s;
// XXX: this implementation is not entirely correct. for example, it
// should escape double-quotes if they appear in the character string.
for (it = string_list.begin(); it != string_list.end(); ++it) {
if (!s.empty())
s.push_back(' ');
s.push_back('"');
s += *it;
s.push_back('"');
}
return (s);
}
Rdata*
TXT::copy() const
{
return (new TXT(toText()));
}
std::string
RRset::toText() const
{
......
......@@ -81,6 +81,7 @@ public:
// (Some) Well-known RRtype constants
static const RRType A;
static const RRType NS;
static const RRType TXT;
static const RRType AAAA;
// more to follow...
......@@ -163,6 +164,27 @@ public:
private:
Name nsname_;
};
// A quick hack implementation of TXT RR. It currently supports only one
// "character-string".
class TXT : public Rdata::Rdata {
public:
TXT() {}
explicit TXT(const std::string& text_data);
unsigned int count() const { return (string_list.size()); }
const RRType& getType() const { return (RRType::TXT); }
static const RRType& getTypeStatic() { return (RRType::TXT); }
std::string toText() const;
void fromWire(Buffer& b, NameDecompressor& c);
void toWire(Buffer& b, NameCompressor& c) const;
bool operator==(const TXT &other) const;
virtual bool operator!=(const TXT &other) const
{ return !(*this == other); }
virtual Rdata* copy() const;
private:
static const unsigned int MAX_CHARACTER_STRING = 255;
std::vector<std::string> string_list;
};
// add MXRdata, etc...
}
......
......@@ -30,6 +30,7 @@ using isc::dns::Rdata::Rdata;
using isc::dns::Rdata::IN::A;
using isc::dns::Rdata::IN::AAAA;
using isc::dns::Rdata::Generic::NS;
using isc::dns::Rdata::Generic::TXT;
using isc::dns::RRset;
using isc::dns::RR;
using isc::dns::Question;
......@@ -52,10 +53,12 @@ TEST_F(RRClassTest, fromToText)
class RRTypeTest : public ::testing::Test {
protected:
RRTypeTest() :
rrtype_a("A"), rrtype_aaaa("AAAA"), rrtype_ns("NS") {}
rrtype_a("A"), rrtype_aaaa("AAAA"), rrtype_ns("NS"), rrtype_txt("TXT")
{}
RRType rrtype_a;
RRType rrtype_aaaa;
RRType rrtype_ns;
RRType rrtype_txt;
};
TEST_F(RRTypeTest, fromToText)
......@@ -63,6 +66,7 @@ TEST_F(RRTypeTest, fromToText)
EXPECT_EQ("A", rrtype_a.toText());
EXPECT_EQ("AAAA", rrtype_aaaa.toText());
EXPECT_EQ("NS", rrtype_ns.toText());
EXPECT_EQ("TXT", rrtype_txt.toText());
}
// The fixture for testing class TTL.
......@@ -135,6 +139,29 @@ TEST_F(Rdata_Generic_NS_Test, fromToText)
EXPECT_EQ("ns.example.com.", rdata.toText());
}
// The fixture for testing Generic/TXT Rdata class
class Rdata_Generic_TXT_Test : public ::testing::Test {
protected:
Rdata_Generic_TXT_Test() : rdata("this is a test string") {}
TXT rdata;
};
TEST_F(Rdata_Generic_TXT_Test, longCharString)
{
EXPECT_THROW(TXT("0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef"),
isc::dns::DNSCharStringTooLong);
}
TEST_F(Rdata_Generic_TXT_Test, fromToText)
{
EXPECT_EQ("\"this is a test string\"", rdata.toText());
}
// The fixture for testing class RRset
class RRsetTest : public ::testing::Test {
protected:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment