Parcourir la source

Merge branch 'master' of ssh://bind10.isc.org/var/bind10/git/bind10

Jelte Jansen il y a 14 ans
Parent
commit
d0181f27a7

+ 10 - 0
ChangeLog

@@ -1,3 +1,13 @@
+  176.  [func]      zhang likun
+	src/lib/cache: Rename one interface: from lookupClosestRRset()
+	to lookupDeepestNS(), and remove one parameter of it.
+	(Trac #492, git ecbfb7cf929d62a018dd4cdc7a841add3d5a35ae)
+
+  175.	[bug]		jerry
+	src/bin/xfrout: Xfrout use the case-sensitive mode to compress
+	names in an AXFR massage.
+	(Trac #253, git 004e382616150f8a2362e94d3458b59bb2710182)
+
   174.	[bug]*		jinmei
   174.	[bug]*		jinmei
 	src/lib/dns: revised dnssectime functions so that they don't rely
 	src/lib/dns: revised dnssectime functions so that they don't rely
 	on the time_t type (whose size varies on different systems, which
 	on the time_t type (whose size varies on different systems, which

+ 23 - 0
src/bin/xfrout/tests/xfrout_test.py

@@ -121,6 +121,29 @@ class TestXfroutSession(unittest.TestCase):
         get_msg = self.sock.read_msg()
         get_msg = self.sock.read_msg()
         self.assertEqual(get_msg.get_rcode().to_text(), "NXDOMAIN")
         self.assertEqual(get_msg.get_rcode().to_text(), "NXDOMAIN")
 
 
+    def test_send_message(self):
+        msg = self.getmsg()
+        msg.make_response()
+        # soa record data with different cases
+        soa_record = (4, 3, 'Example.com.', 'com.Example.', 3600, 'SOA', None, 'master.Example.com. admin.exAmple.com. 1234 3600 1800 2419200 7200')
+        rrset_soa = self.xfrsess._create_rrset_from_db_record(soa_record)
+        msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
+        self.xfrsess._send_message(self.sock, msg)
+        send_out_data = self.sock.readsent()[2:]
+
+        # CASE_INSENSITIVE compression mode
+        render = MessageRenderer();
+        render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
+        msg.to_wire(render)
+        self.assertNotEqual(render.get_data(), send_out_data)
+
+        # CASE_SENSITIVE compression mode
+        render.clear()
+        render.set_compress_mode(MessageRenderer.CASE_SENSITIVE)
+        render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
+        msg.to_wire(render)
+        self.assertEqual(render.get_data(), send_out_data)
+
     def test_clear_message(self):
     def test_clear_message(self):
         msg = self.getmsg()
         msg = self.getmsg()
         qid = msg.get_qid()
         qid = msg.get_qid()

+ 3 - 0
src/bin/xfrout/xfrout.py.in

@@ -170,6 +170,9 @@ class XfroutSession(BaseRequestHandler):
 
 
     def _send_message(self, sock_fd, msg):
     def _send_message(self, sock_fd, msg):
         render = MessageRenderer()
         render = MessageRenderer()
+        # As defined in RFC5936 section3.4, perform case-preserving name
+        # compression for AXFR message.
+        render.set_compress_mode(MessageRenderer.CASE_SENSITIVE)
         render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
         render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
         msg.to_wire(render)
         msg.to_wire(render)
         header_len = struct.pack('H', socket.htons(render.get_length()))
         header_len = struct.pack('H', socket.htons(render.get_length()))

+ 3 - 4
src/lib/cache/resolver_cache.cc

@@ -175,10 +175,10 @@ ResolverCache::lookup(const isc::dns::Name& qname,
 }
 }
 
 
 isc::dns::RRsetPtr
 isc::dns::RRsetPtr
-ResolverCache::lookupClosestRRset(const isc::dns::Name& qname,
-                                  const isc::dns::RRType& qtype,
-                                  const isc::dns::RRClass& qclass) const
+ResolverCache::lookupDeepestNS(const isc::dns::Name& qname,
+                               const isc::dns::RRClass& qclass) const
 {
 {
+    isc::dns::RRType qtype = RRType::NS();
     ResolverClassCache* cc = getClassCache(qclass);
     ResolverClassCache* cc = getClassCache(qclass);
     if (cc) {
     if (cc) {
         unsigned int count = qname.getLabelCount();
         unsigned int count = qname.getLabelCount();
@@ -199,7 +199,6 @@ ResolverCache::lookupClosestRRset(const isc::dns::Name& qname,
 
 
 bool
 bool
 ResolverCache::update(const isc::dns::Message& msg) {
 ResolverCache::update(const isc::dns::Message& msg) {
-    
     QuestionIterator iter = msg.beginQuestion();
     QuestionIterator iter = msg.beginQuestion();
     ResolverClassCache* cc = getClassCache((*iter)->getClass());
     ResolverClassCache* cc = getClassCache((*iter)->getClass());
     if (cc) {
     if (cc) {

+ 14 - 15
src/lib/cache/resolver_cache.h

@@ -241,28 +241,27 @@ public:
                               const isc::dns::RRType& qtype,
                               const isc::dns::RRType& qtype,
                               const isc::dns::RRClass& qclass) const;
                               const isc::dns::RRClass& qclass) const;
 
 
-    /// \brief Look up closest rrset in cache.
+    /// \brief Look up closest enclosing NS rrset in cache.
     ///
     ///
     /// \param qname The query name to look up
     /// \param qname The query name to look up
-    /// \param qtype The query type to look up
     /// \param qclass The query class to look up
     /// \param qclass The query class to look up
     ///
     ///
-    /// \return return the shared_ptr of rrset if it can be found in
-    ///         cache, or else return NULL.
+    /// \return return the shared_ptr of closest enclosing ns rrset
+    ///         if it can be found in cache, or else return NULL.
     ///
     ///
-    /// Currently the implementation is: search exact rrset
-    /// label by lable, If the rrset can't be found, remove the last
+    /// Currently the implementation is: search exact ns rrset
+    /// label by lable, If the ns rrset can't be found, remove the last
     /// label, then search again. The efficiency may be very low when
     /// label, then search again. The efficiency may be very low when
-    /// the name of rrset is very long but it's closest rrset's name
-    /// is very short.
-    /// If a good perfermance is needed when looking up the closest rrset,
-    /// rrset cache structure(HashTable) should be redesigned. By using
-    /// HashTable, it can only garantee the performance for looking
-    /// up exact rrset.
+    /// the name is very long but it's closest rrset's name is very short.
+    ///
+    /// If a good perfermance is needed when looking up the closest
+    /// enclosing ns rrset, cache structure(HashTable) should be
+    /// redesigned. By using HashTable, it can only garantee the
+    /// performance for looking up exact rrset.
+    ///
     /// So here there is another question, which rrset looking up interface
     /// So here there is another question, which rrset looking up interface
-    /// is used frequently? Exact or closest looking up.
-    isc::dns::RRsetPtr lookupClosestRRset(const isc::dns::Name& qname,
-                              const isc::dns::RRType& qtype,
+    /// is used frequently? Exact or closest enclosing ns looking up.
+    isc::dns::RRsetPtr lookupDeepestNS(const isc::dns::Name& qname,
                               const isc::dns::RRClass& qclass) const;
                               const isc::dns::RRClass& qclass) const;
     //@}
     //@}
 
 

+ 3 - 6
src/lib/cache/tests/resolver_cache_unittest.cc

@@ -113,18 +113,15 @@ TEST_F(ResolverCacheTest, testLookupClosestRRset) {
 
 
     Name qname("www.test.example.com.");
     Name qname("www.test.example.com.");
 
 
-    RRsetPtr rrset_ptr = cache->lookupClosestRRset(qname, RRType::NS(),
-                                                  RRClass::IN());
+    RRsetPtr rrset_ptr = cache->lookupDeepestNS(qname, RRClass::IN());
     EXPECT_TRUE(rrset_ptr);
     EXPECT_TRUE(rrset_ptr);
     EXPECT_EQ(rrset_ptr->getName(), Name("example.com."));
     EXPECT_EQ(rrset_ptr->getName(), Name("example.com."));
 
 
-    rrset_ptr = cache->lookupClosestRRset(Name("example.com."),
-                                         RRType::NS(), RRClass::IN());
+    rrset_ptr = cache->lookupDeepestNS(Name("example.com."), RRClass::IN());
     EXPECT_TRUE(rrset_ptr);
     EXPECT_TRUE(rrset_ptr);
     EXPECT_EQ(rrset_ptr->getName(), Name("example.com."));
     EXPECT_EQ(rrset_ptr->getName(), Name("example.com."));
 
 
-    rrset_ptr = cache->lookupClosestRRset(Name("com."),
-                                         RRType::NS(), RRClass::IN());
+    rrset_ptr = cache->lookupDeepestNS(Name("com."), RRClass::IN());
     EXPECT_FALSE(rrset_ptr);
     EXPECT_FALSE(rrset_ptr);
 }
 }
 
 

+ 44 - 1
src/lib/dns/python/messagerenderer_python.cc

@@ -37,9 +37,10 @@ static PyObject* MessageRenderer_getData(s_MessageRenderer* self);
 static PyObject* MessageRenderer_getLength(s_MessageRenderer* self);
 static PyObject* MessageRenderer_getLength(s_MessageRenderer* self);
 static PyObject* MessageRenderer_isTruncated(s_MessageRenderer* self);
 static PyObject* MessageRenderer_isTruncated(s_MessageRenderer* self);
 static PyObject* MessageRenderer_getLengthLimit(s_MessageRenderer* self);
 static PyObject* MessageRenderer_getLengthLimit(s_MessageRenderer* self);
-// TODO: set/get compressmode
+static PyObject* MessageRenderer_getCompressMode(s_MessageRenderer* self);
 static PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
 static PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
 static PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
 static PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
+static PyObject* MessageRenderer_setCompressMode(s_MessageRenderer* self, PyObject* args);
 static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
 static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
 
 
 static PyMethodDef MessageRenderer_methods[] = {
 static PyMethodDef MessageRenderer_methods[] = {
@@ -51,10 +52,14 @@ static PyMethodDef MessageRenderer_methods[] = {
       "Returns True if the data is truncated" },
       "Returns True if the data is truncated" },
     { "get_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_getLengthLimit), METH_NOARGS,
     { "get_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_getLengthLimit), METH_NOARGS,
       "Returns the length limit of the data" },
       "Returns the length limit of the data" },
+    { "get_compress_mode", reinterpret_cast<PyCFunction>(MessageRenderer_getCompressMode), METH_NOARGS,
+      "Returns the current compression mode" },
     { "set_truncated", reinterpret_cast<PyCFunction>(MessageRenderer_setTruncated), METH_NOARGS,
     { "set_truncated", reinterpret_cast<PyCFunction>(MessageRenderer_setTruncated), METH_NOARGS,
       "Sets truncated to true" },
       "Sets truncated to true" },
     { "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
     { "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
       "Sets the length limit of the data to the given number" },
       "Sets the length limit of the data to the given number" },
+    { "set_compress_mode", reinterpret_cast<PyCFunction>(MessageRenderer_setCompressMode), METH_VARARGS,
+      "Sets the compression mode of the MessageRenderer" },
     { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
     { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
       METH_NOARGS,
       METH_NOARGS,
       "Clear the internal buffer and other internal resources." },
       "Clear the internal buffer and other internal resources." },
@@ -159,6 +164,11 @@ MessageRenderer_getLengthLimit(s_MessageRenderer* self) {
 }
 }
 
 
 static PyObject*
 static PyObject*
+MessageRenderer_getCompressMode(s_MessageRenderer* self) {
+    return (Py_BuildValue("I", self->messagerenderer->getCompressMode()));
+}
+
+static PyObject*
 MessageRenderer_setTruncated(s_MessageRenderer* self) {
 MessageRenderer_setTruncated(s_MessageRenderer* self) {
     self->messagerenderer->setTruncated();
     self->messagerenderer->setTruncated();
     Py_RETURN_NONE;
     Py_RETURN_NONE;
@@ -177,6 +187,31 @@ MessageRenderer_setLengthLimit(s_MessageRenderer* self,
 }
 }
 
 
 static PyObject*
 static PyObject*
+MessageRenderer_setCompressMode(s_MessageRenderer* self,
+                               PyObject* args)
+{
+    unsigned int mode;
+    if (!PyArg_ParseTuple(args, "I", &mode)) {
+        return (NULL);
+    }
+
+    if (mode == MessageRenderer::CASE_INSENSITIVE) {
+        self->messagerenderer->setCompressMode(MessageRenderer::CASE_INSENSITIVE);
+        // If we return NULL it is seen as an error, so use this for
+        // None returns, it also applies to CASE_SENSITIVE.
+        Py_RETURN_NONE;
+    } else if (mode == MessageRenderer::CASE_SENSITIVE) {
+        self->messagerenderer->setCompressMode(MessageRenderer::CASE_SENSITIVE);
+        Py_RETURN_NONE;
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+                        "MessageRenderer compress mode must be MessageRenderer.CASE_INSENSITIVE"
+                        "or MessageRenderer.CASE_SENSITIVE");
+        return (NULL);
+    }
+}
+
+static PyObject*
 MessageRenderer_clear(s_MessageRenderer* self) {
 MessageRenderer_clear(s_MessageRenderer* self) {
     self->messagerenderer->clear();
     self->messagerenderer->clear();
     Py_RETURN_NONE;
     Py_RETURN_NONE;
@@ -203,6 +238,14 @@ initModulePart_MessageRenderer(PyObject* mod) {
         return (false);
         return (false);
     }
     }
     Py_INCREF(&messagerenderer_type);
     Py_INCREF(&messagerenderer_type);
+
+    // Class variables
+    // These are added to the tp_dict of the type object
+    addClassVariable(messagerenderer_type, "CASE_INSENSITIVE",
+                     Py_BuildValue("I", MessageRenderer::CASE_INSENSITIVE));
+    addClassVariable(messagerenderer_type, "CASE_SENSITIVE",
+                     Py_BuildValue("I", MessageRenderer::CASE_SENSITIVE));
+
     PyModule_AddObject(mod, "MessageRenderer",
     PyModule_AddObject(mod, "MessageRenderer",
                        reinterpret_cast<PyObject*>(&messagerenderer_type));
                        reinterpret_cast<PyObject*>(&messagerenderer_type));
     
     

+ 24 - 4
src/lib/dns/python/tests/messagerenderer_python_test.py

@@ -28,7 +28,7 @@ class MessageRendererTest(unittest.TestCase):
         c = RRClass("IN")
         c = RRClass("IN")
         t = RRType("A")
         t = RRType("A")
         ttl = RRTTL("3600")
         ttl = RRTTL("3600")
-        
+
         message = Message(Message.RENDER)
         message = Message(Message.RENDER)
         message.set_qid(123)
         message.set_qid(123)
         message.set_opcode(Opcode.QUERY())
         message.set_opcode(Opcode.QUERY())
@@ -56,14 +56,14 @@ class MessageRendererTest(unittest.TestCase):
         self.message1.to_wire(self.renderer1)
         self.message1.to_wire(self.renderer1)
         self.message2.to_wire(self.renderer2)
         self.message2.to_wire(self.renderer2)
         self.message2.to_wire(self.renderer3)
         self.message2.to_wire(self.renderer3)
-        
-    
+
+
     def test_messagerenderer_get_data(self):
     def test_messagerenderer_get_data(self):
         data1 = b'\x00{\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\x03com\x00\x00\x01\x00\x01'
         data1 = b'\x00{\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\x03com\x00\x00\x01\x00\x01'
         self.assertEqual(data1, self.renderer1.get_data())
         self.assertEqual(data1, self.renderer1.get_data())
         data2 = b'\x00{\x84\x00\x00\x01\x00\x00\x00\x02\x00\x00\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02b\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02c'
         data2 = b'\x00{\x84\x00\x00\x01\x00\x00\x00\x02\x00\x00\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02b\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02c'
         self.assertEqual(data2, self.renderer2.get_data())
         self.assertEqual(data2, self.renderer2.get_data())
-        
+
     def test_messagerenderer_get_length(self):
     def test_messagerenderer_get_length(self):
         self.assertEqual(29, self.renderer1.get_length())
         self.assertEqual(29, self.renderer1.get_length())
         self.assertEqual(61, self.renderer2.get_length())
         self.assertEqual(61, self.renderer2.get_length())
@@ -79,6 +79,14 @@ class MessageRendererTest(unittest.TestCase):
         self.assertEqual(512, self.renderer2.get_length_limit())
         self.assertEqual(512, self.renderer2.get_length_limit())
         self.assertEqual(50, self.renderer3.get_length_limit())
         self.assertEqual(50, self.renderer3.get_length_limit())
 
 
+    def test_messagerenderer_get_compress_mode(self):
+        self.assertEqual(MessageRenderer.CASE_INSENSITIVE,
+                         self.renderer1.get_compress_mode())
+        self.assertEqual(MessageRenderer.CASE_INSENSITIVE,
+                         self.renderer2.get_compress_mode())
+        self.assertEqual(MessageRenderer.CASE_INSENSITIVE,
+                         self.renderer3.get_compress_mode())
+
     def test_messagerenderer_set_truncated(self):
     def test_messagerenderer_set_truncated(self):
         self.assertFalse(self.renderer1.is_truncated())
         self.assertFalse(self.renderer1.is_truncated())
         self.renderer1.set_truncated()
         self.renderer1.set_truncated()
@@ -91,5 +99,17 @@ class MessageRendererTest(unittest.TestCase):
         self.assertEqual(1024, renderer.get_length_limit())
         self.assertEqual(1024, renderer.get_length_limit())
         self.assertRaises(TypeError, renderer.set_length_limit, "wrong")
         self.assertRaises(TypeError, renderer.set_length_limit, "wrong")
 
 
+    def test_messagerenderer_set_compress_mode(self):
+        renderer = MessageRenderer()
+        self.assertEqual(MessageRenderer.CASE_INSENSITIVE,
+                         renderer.get_compress_mode())
+        renderer.set_compress_mode(MessageRenderer.CASE_SENSITIVE)
+        self.assertEqual(MessageRenderer.CASE_SENSITIVE,
+                         renderer.get_compress_mode())
+        renderer.set_compress_mode(MessageRenderer.CASE_INSENSITIVE)
+        self.assertEqual(MessageRenderer.CASE_INSENSITIVE,
+                         renderer.get_compress_mode())
+        self.assertRaises(TypeError, renderer.set_compress_mode, "wrong")
+
 if __name__ == '__main__':
 if __name__ == '__main__':
     unittest.main()
     unittest.main()