Browse Source

supported MX RR

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/f2f200910@218 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 15 years ago
parent
commit
bcfa14e582
3 changed files with 75 additions and 2 deletions
  1. 41 2
      src/lib/dns/rrset.cc
  2. 21 0
      src/lib/dns/rrset.h
  3. 13 0
      src/lib/dns/rrset_unittest.cc

+ 41 - 2
src/lib/dns/rrset.cc

@@ -40,6 +40,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::MX;
 using isc::dns::Rdata::Generic::SOA;
 using isc::dns::Rdata::Generic::TXT;
 using isc::dns::RRset;
@@ -89,6 +90,8 @@ RRType::RRType(const std::string& typestr)
         typeval_ = 2;
     else if (typestr == "SOA")
         typeval_ = 6;
+    else if (typestr == "MX")
+        typeval_ = 15;
     else if (typestr == "TXT")
         typeval_ = 16;
     else if (typestr == "AAAA")
@@ -106,6 +109,8 @@ RRType::toText() const
         return ("NS");
     else if (typeval_ == 6)
         return ("SOA");
+    else if (typeval_ == 15)
+        return ("MX");
     else if (typeval_ == 16)
         return ("TXT");
     else if (typeval_ == 28)
@@ -126,6 +131,7 @@ RRType::toWire(Buffer& buffer) const
 const RRType RRType::A("A");
 const RRType RRType::NS("NS");
 const RRType RRType::SOA("SOA");
+const RRType RRType::MX("MX");
 const RRType RRType::TXT("TXT");
 const RRType RRType::AAAA("AAAA");
 // ...more to follow
@@ -174,7 +180,7 @@ RdataFactoryRegister::RdataFactoryRegister()
     text_rdata_factory_repository.insert(pair<RRClassTypePair, TextRdataFactory>
                              (RRClassTypePair(RRClass::IN, RRType::AAAA),
                               createDataFromText<isc::dns::Rdata::IN::AAAA>));
-    //XXX: NS/TXT/SOA belongs to the 'generic' class.  should revisit it.
+    //XXX: NS/TXT/SOA?MX belongs to the 'generic' class.  should revisit it.
     text_rdata_factory_repository.insert(pair<RRClassTypePair, TextRdataFactory>
                              (RRClassTypePair(RRClass::IN, RRType::NS),
                               createDataFromText<isc::dns::Rdata::Generic::NS>));
@@ -182,7 +188,7 @@ RdataFactoryRegister::RdataFactoryRegister()
                              (RRClassTypePair(RRClass::IN, RRType::TXT),
                               createDataFromText<isc::dns::Rdata::Generic::TXT>));
 
-    // "fromText" for SOA is not yet implemented: parsing multi-field RDATA
+    // "fromText" for SOA/MX is not yet implemented: parsing multi-field RDATA
     // is not trivial.
 
     // XXX: we should treat class-agnostic type accordingly.
@@ -200,6 +206,9 @@ RdataFactoryRegister::RdataFactoryRegister()
                              (RRClassTypePair(RRClass::IN, RRType::NS),
                               createDataFromWire<isc::dns::Rdata::Generic::NS>));
     wire_rdata_factory_repository.insert(pair<RRClassTypePair, WireRdataFactory>
+                             (RRClassTypePair(RRClass::IN, RRType::MX),
+                              createDataFromWire<isc::dns::Rdata::Generic::MX>));
+    wire_rdata_factory_repository.insert(pair<RRClassTypePair, WireRdataFactory>
                              (RRClassTypePair(RRClass::IN, RRType::SOA),
                               createDataFromWire<isc::dns::Rdata::Generic::SOA>));
 }
@@ -382,6 +391,36 @@ SOA::copy() const
                     expire_, ttl_));
 }
 
+MX::MX(Buffer& buffer, NameDecompressor& decompressor)
+{
+    size_t len = buffer.readUint16();
+    preference_ = buffer.readUint16();
+    mxname_ = Name(buffer, decompressor);
+}
+
+void
+MX::toWire(Buffer& buffer, NameCompressor& compressor) const
+{
+    // XXX: note that a complete implementation cannot be this simple
+    // because we need to disable compression for the NS name.
+    buffer.writeUint16(mxname_.getLength() + sizeof(preference_));
+    buffer.writeUint16(preference_);
+    mxname_.toWire(buffer, compressor);
+}
+
+std::string
+MX::toText() const
+{
+    return (boost::lexical_cast<std::string>(preference_) + " " +
+            mxname_.toText());
+}
+
+Rdata*
+MX::copy() const
+{
+    return (new MX(preference_, mxname_.toText()));
+}
+
 TXT::TXT(const std::string& text_data)
 {
     size_t length = text_data.size();

+ 21 - 0
src/lib/dns/rrset.h

@@ -82,6 +82,7 @@ public:
     static const RRType A;
     static const RRType NS;
     static const RRType SOA;
+    static const RRType MX;
     static const RRType TXT;
     static const RRType AAAA;
     // more to follow...
@@ -167,6 +168,26 @@ private:
     Name nsname_;
 };
 
+class MX : public Rdata::Rdata {
+public:
+    MX() {}
+    explicit MX(uint16_t preference, const std::string& namestr) :
+        preference_(preference), mxname_(namestr) {}
+    explicit MX(Buffer& buffer, NameDecompressor& decompressor);
+    unsigned int count() const { return (1); }
+    const RRType& getType() const { return (RRType::MX); }
+    static const RRType& getTypeStatic() { return (RRType::MX); }
+    std::string toText() const;
+    void toWire(Buffer& buffer, NameCompressor& compressor) const;
+    bool operator==(const MX& other) const
+    { return (preference_ == other.preference_ && mxname_ == other.mxname_); }
+    virtual bool operator!=(const MX &other) const { return !(*this == other); }
+    virtual Rdata* copy() const;
+private:
+    uint16_t preference_;
+    Name mxname_;
+};
+
 class SOA : public Rdata::Rdata {
 public:
     SOA() {}

+ 13 - 0
src/lib/dns/rrset_unittest.cc

@@ -31,6 +31,7 @@ using isc::dns::Rdata::IN::A;
 using isc::dns::Rdata::IN::AAAA;
 using isc::dns::Rdata::Generic::NS;
 using isc::dns::Rdata::Generic::SOA;
+using isc::dns::Rdata::Generic::MX;
 using isc::dns::Rdata::Generic::TXT;
 using isc::dns::RRset;
 using isc::dns::RR;
@@ -156,6 +157,18 @@ TEST_F(Rdata_Generic_SOA_Test, fromToText)
     EXPECT_EQ("ns.example.com. root.example.com. 2009102700 7200 3600 24796800 1200", rdata.toText());
 }
 
+// The fixture for testing class Generic/MX Rdata
+class Rdata_Generic_MX_Test : public ::testing::Test {
+protected:
+    Rdata_Generic_MX_Test() { rdata = MX(10, "mail.example.com"); }
+    MX rdata;
+};
+
+TEST_F(Rdata_Generic_MX_Test, fromToText)
+{
+    EXPECT_EQ("10 mail.example.com.", rdata.toText());
+}
+
 // The fixture for testing Generic/TXT Rdata class
 class Rdata_Generic_TXT_Test : public ::testing::Test {
 protected: