Commit d0181f27 authored by Jelte Jansen's avatar Jelte Jansen
Browse files
parents cf131c0c fcb8add5
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
src/lib/dns: revised dnssectime functions so that they don't rely
on the time_t type (whose size varies on different systems, which
......
......@@ -121,6 +121,29 @@ class TestXfroutSession(unittest.TestCase):
get_msg = self.sock.read_msg()
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):
msg = self.getmsg()
qid = msg.get_qid()
......
......@@ -170,6 +170,9 @@ class XfroutSession(BaseRequestHandler):
def _send_message(self, sock_fd, msg):
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)
msg.to_wire(render)
header_len = struct.pack('H', socket.htons(render.get_length()))
......
......@@ -175,10 +175,10 @@ ResolverCache::lookup(const isc::dns::Name& qname,
}
isc::dns::RRsetPtr
ResolverCache::lookupClosestRRset(const isc::dns::Name& qname,
const isc::dns::RRType& qtype,
ResolverCache::lookupDeepestNS(const isc::dns::Name& qname,
const isc::dns::RRClass& qclass) const
{
isc::dns::RRType qtype = RRType::NS();
ResolverClassCache* cc = getClassCache(qclass);
if (cc) {
unsigned int count = qname.getLabelCount();
......@@ -199,7 +199,6 @@ ResolverCache::lookupClosestRRset(const isc::dns::Name& qname,
bool
ResolverCache::update(const isc::dns::Message& msg) {
QuestionIterator iter = msg.beginQuestion();
ResolverClassCache* cc = getClassCache((*iter)->getClass());
if (cc) {
......
......@@ -241,28 +241,27 @@ public:
const isc::dns::RRType& qtype,
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 qtype The query type 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
/// 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
/// 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;
//@}
......
......@@ -113,18 +113,15 @@ TEST_F(ResolverCacheTest, testLookupClosestRRset) {
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_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_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);
}
......
......@@ -37,9 +37,10 @@ static PyObject* MessageRenderer_getData(s_MessageRenderer* self);
static PyObject* MessageRenderer_getLength(s_MessageRenderer* self);
static PyObject* MessageRenderer_isTruncated(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_setLengthLimit(s_MessageRenderer* self, PyObject* args);
static PyObject* MessageRenderer_setCompressMode(s_MessageRenderer* self, PyObject* args);
static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
static PyMethodDef MessageRenderer_methods[] = {
......@@ -51,10 +52,14 @@ static PyMethodDef MessageRenderer_methods[] = {
"Returns True if the data is truncated" },
{ "get_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_getLengthLimit), METH_NOARGS,
"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,
"Sets truncated to true" },
{ "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
"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),
METH_NOARGS,
"Clear the internal buffer and other internal resources." },
......@@ -158,6 +163,11 @@ MessageRenderer_getLengthLimit(s_MessageRenderer* self) {
return (Py_BuildValue("I", self->messagerenderer->getLengthLimit()));
}
static PyObject*
MessageRenderer_getCompressMode(s_MessageRenderer* self) {
return (Py_BuildValue("I", self->messagerenderer->getCompressMode()));
}
static PyObject*
MessageRenderer_setTruncated(s_MessageRenderer* self) {
self->messagerenderer->setTruncated();
......@@ -176,6 +186,31 @@ MessageRenderer_setLengthLimit(s_MessageRenderer* self,
Py_RETURN_NONE;
}
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) {
self->messagerenderer->clear();
......@@ -203,6 +238,14 @@ initModulePart_MessageRenderer(PyObject* mod) {
return (false);
}
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",
reinterpret_cast<PyObject*>(&messagerenderer_type));
......
......@@ -79,6 +79,14 @@ class MessageRendererTest(unittest.TestCase):
self.assertEqual(512, self.renderer2.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):
self.assertFalse(self.renderer1.is_truncated())
self.renderer1.set_truncated()
......@@ -91,5 +99,17 @@ class MessageRendererTest(unittest.TestCase):
self.assertEqual(1024, renderer.get_length_limit())
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__':
unittest.main()
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