Commit 0555ab65 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[master] Merge branch 'trac915'

with fixing (trivial) conflicts in:
	src/lib/dns/python/Makefile.am
	src/lib/dns/python/tsigerror_python.cc
Also moved tsigerror_python_inc.cc to EXTRA_DIST because it doesn't have
to be compiled separately.
parents 080db7e6 23d63caf
......@@ -777,6 +777,7 @@ AC_CONFIG_FILES([Makefile
src/lib/util/io/Makefile
src/lib/util/io/tests/Makefile
src/lib/util/unittests/Makefile
src/lib/util/pyunittests/Makefile
src/lib/util/tests/Makefile
tests/Makefile
tests/system/Makefile
......
......@@ -5,10 +5,16 @@ AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
pyexec_LTLIBRARIES = pydnspp.la
pydnspp_la_SOURCES = pydnspp.cc pydnspp_common.cc
pydnspp_la_SOURCES = pydnspp.cc pydnspp_common.cc pydnspp_towire.h
pydnspp_la_SOURCES += name_python.cc name_python.h
pydnspp_la_SOURCES += messagerenderer_python.cc messagerenderer_python.h
pydnspp_la_SOURCES += rcode_python.cc rcode_python.h
pydnspp_la_SOURCES += tsigkey_python.cc tsigkey_python.h
pydnspp_la_SOURCES += tsigerror_python.cc tsigerror_python.h
pydnspp_la_SOURCES += tsigerror_python_inc.cc
pydnspp_la_SOURCES += tsig_rdata_python.cc tsig_rdata_python.h
pydnspp_la_SOURCES += tsigrecord_python.cc tsigrecord_python.h
pydnspp_la_SOURCES += tsig_python.cc tsig_python.h
pydnspp_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
pydnspp_la_LDFLAGS = $(PYTHON_LDFLAGS)
......@@ -16,19 +22,15 @@ pydnspp_la_LDFLAGS = $(PYTHON_LDFLAGS)
# rules
EXTRA_DIST = pydnspp_common.h
EXTRA_DIST += edns_python.cc
EXTRA_DIST += messagerenderer_python.cc
EXTRA_DIST += message_python.cc
EXTRA_DIST += rrclass_python.cc
EXTRA_DIST += name_python.cc
EXTRA_DIST += opcode_python.cc
EXTRA_DIST += rcode_python.cc
EXTRA_DIST += rrset_python.cc
EXTRA_DIST += question_python.cc
EXTRA_DIST += rrttl_python.cc
EXTRA_DIST += rdata_python.cc
EXTRA_DIST += rrtype_python.cc
EXTRA_DIST += tsigkey_python.cc
EXTRA_DIST += tsig_python.cc
EXTRA_DIST += tsigerror_python_inc.cc
# Python prefers .so, while some OSes (specifically MacOS) use a different
# suffix for dynamic objects. -module is necessary to work this around.
......
......@@ -108,7 +108,7 @@ PyMethodDef EDNS_methods[] = {
// Most of the functions are not actually implemented and NULL here.
PyTypeObject edns_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"libdns_python.EDNS",
"pydnspp.EDNS",
sizeof(s_EDNS), // tp_basicsize
0, // tp_itemsize
(destructor)EDNS_destroy, // tp_dealloc
......@@ -203,7 +203,7 @@ EDNS_init(s_EDNS* self, PyObject* args) {
// in this context so that we can share the try-catch logic with
// EDNS_createFromRR() (see below).
uint8_t extended_rcode;
self->edns = createFromRR(*name->name, *rrclass->rrclass,
self->edns = createFromRR(*name->cppobj, *rrclass->rrclass,
*rrtype->rrtype, *rrttl->rrttl,
*rdata->rdata, extended_rcode);
return (self->edns != NULL ? 0 : -1);
......@@ -334,7 +334,7 @@ EDNS_createFromRR(const s_EDNS* null_self, PyObject* args) {
return (NULL);
}
edns_obj->edns = createFromRR(*name->name, *rrclass->rrclass,
edns_obj->edns = createFromRR(*name->cppobj, *rrclass->rrclass,
*rrtype->rrtype, *rrttl->rrttl,
*rdata->rdata, extended_rcode);
if (edns_obj->edns != NULL) {
......
......@@ -14,6 +14,8 @@
#include <exceptions/exceptions.h>
#include <dns/message.h>
#include <dns/rcode.h>
using namespace isc::dns;
using namespace isc::util;
......@@ -65,6 +67,7 @@ PyObject* Message_getOpcode(s_Message* self);
PyObject* Message_setOpcode(s_Message* self, PyObject* args);
PyObject* Message_getEDNS(s_Message* self);
PyObject* Message_setEDNS(s_Message* self, PyObject* args);
PyObject* Message_getTSIGRecord(s_Message* self);
PyObject* Message_getRRCount(s_Message* self, PyObject* args);
// use direct iterators for these? (or simply lists for now?)
PyObject* Message_getQuestion(s_Message* self);
......@@ -123,6 +126,11 @@ PyMethodDef Message_methods[] = {
{ "set_edns", reinterpret_cast<PyCFunction>(Message_setEDNS), METH_VARARGS,
"Set EDNS for the message."
},
{ "get_tsig_record",
reinterpret_cast<PyCFunction>(Message_getTSIGRecord), METH_NOARGS,
"Return, if any, the TSIG record contained in the received message. "
"If no TSIG RR is set in the message, None will be returned."
},
{ "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
"Returns the number of RRs contained in the given section." },
{ "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
......@@ -441,6 +449,29 @@ Message_setEDNS(s_Message* self, PyObject* args) {
}
}
PyObject*
Message_getTSIGRecord(s_Message* self) {
try {
const TSIGRecord* tsig_record = self->message->getTSIGRecord();
if (tsig_record == NULL) {
Py_RETURN_NONE;
}
return (createTSIGRecordObject(*tsig_record));
} catch (const InvalidMessageOperation& ex) {
PyErr_SetString(po_InvalidMessageOperation, ex.what());
} catch (const exception& ex) {
const string ex_what =
"Unexpected failure in getting TSIGRecord from message: " +
string(ex.what());
PyErr_SetString(po_IscException, ex_what.c_str());
} catch (...) {
PyErr_SetString(PyExc_SystemError, "Unexpected failure in "
"getting TSIGRecord from message");
}
return (NULL);
}
PyObject*
Message_getRRCount(s_Message* self, PyObject* args) {
unsigned int section;
......@@ -652,13 +683,12 @@ Message_toWire(s_Message* self, PyObject* args) {
s_TSIGContext* tsig_ctx = NULL;
if (PyArg_ParseTuple(args, "O!|O!", &messagerenderer_type, &mr,
&tsig_context_type, &tsig_ctx)) {
&tsigcontext_type, &tsig_ctx)) {
try {
if (tsig_ctx == NULL) {
self->message->toWire(*mr->messagerenderer);
} else {
self->message->toWire(*mr->messagerenderer,
*tsig_ctx->tsig_ctx);
self->message->toWire(*mr->messagerenderer, *tsig_ctx->cppobj);
}
// If we return NULL it is seen as an error, so use this for
// None returns
......
......@@ -12,39 +12,41 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <Python.h>
#include <util/buffer.h>
#include <dns/messagerenderer.h>
// For each class, we need a struct, a helper functions (init, destroy,
// and static wrappers around the methods we export), a list of methods,
// and a type description
#include "pydnspp_common.h"
#include "messagerenderer_python.h"
using namespace isc::dns;
using namespace isc::dns::python;
using namespace isc::util;
// MessageRenderer
// since we don't use *Buffer in the python version (but work with
// the already existing bytearray type where we use these custom buffers
// in c++, we need to keep track of one here.
class s_MessageRenderer : public PyObject {
public:
OutputBuffer* outputbuffer;
MessageRenderer* messagerenderer;
};
s_MessageRenderer::s_MessageRenderer() : outputbuffer(NULL),
messagerenderer(NULL)
{
}
static int MessageRenderer_init(s_MessageRenderer* self);
static void MessageRenderer_destroy(s_MessageRenderer* self);
namespace {
int MessageRenderer_init(s_MessageRenderer* self);
void MessageRenderer_destroy(s_MessageRenderer* self);
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);
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);
PyObject* MessageRenderer_getData(s_MessageRenderer* self);
PyObject* MessageRenderer_getLength(s_MessageRenderer* self);
PyObject* MessageRenderer_isTruncated(s_MessageRenderer* self);
PyObject* MessageRenderer_getLengthLimit(s_MessageRenderer* self);
PyObject* MessageRenderer_getCompressMode(s_MessageRenderer* self);
PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
PyObject* MessageRenderer_setCompressMode(s_MessageRenderer* self, PyObject* args);
PyObject* MessageRenderer_clear(s_MessageRenderer* self);
static PyMethodDef MessageRenderer_methods[] = {
PyMethodDef MessageRenderer_methods[] = {
{ "get_data", reinterpret_cast<PyCFunction>(MessageRenderer_getData), METH_NOARGS,
"Returns the data as a bytes() object" },
{ "get_length", reinterpret_cast<PyCFunction>(MessageRenderer_getLength), METH_NOARGS,
......@@ -67,69 +69,14 @@ static PyMethodDef MessageRenderer_methods[] = {
{ NULL, NULL, 0, NULL }
};
static PyTypeObject messagerenderer_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"pydnspp.MessageRenderer",
sizeof(s_MessageRenderer), // tp_basicsize
0, // tp_itemsize
(destructor)MessageRenderer_destroy,// tp_dealloc
NULL, // tp_print
NULL, // tp_getattr
NULL, // tp_setattr
NULL, // tp_reserved
NULL, // tp_repr
NULL, // tp_as_number
NULL, // tp_as_sequence
NULL, // tp_as_mapping
NULL, // tp_hash
NULL, // tp_call
NULL, // tp_str
NULL, // tp_getattro
NULL, // tp_setattro
NULL, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"The MessageRenderer class encapsulates implementation details "
"of rendering a DNS message into a buffer in wire format. "
"In effect, it's simply responsible for name compression at least in the "
"current implementation. A MessageRenderer class object manages the "
"positions of names rendered in a buffer and uses that information to render "
"subsequent names with compression.",
NULL, // tp_traverse
NULL, // tp_clear
NULL, // tp_richcompare
0, // tp_weaklistoffset
NULL, // tp_iter
NULL, // tp_iternext
MessageRenderer_methods, // tp_methods
NULL, // tp_members
NULL, // tp_getset
NULL, // tp_base
NULL, // tp_dict
NULL, // tp_descr_get
NULL, // tp_descr_set
0, // tp_dictoffset
(initproc)MessageRenderer_init, // tp_init
NULL, // tp_alloc
PyType_GenericNew, // tp_new
NULL, // tp_free
NULL, // tp_is_gc
NULL, // tp_bases
NULL, // tp_mro
NULL, // tp_cache
NULL, // tp_subclasses
NULL, // tp_weaklist
NULL, // tp_del
0 // tp_version_tag
};
static int
int
MessageRenderer_init(s_MessageRenderer* self) {
self->outputbuffer = new OutputBuffer(4096);
self->messagerenderer = new MessageRenderer(*self->outputbuffer);
return (0);
}
static void
void
MessageRenderer_destroy(s_MessageRenderer* self) {
delete self->messagerenderer;
delete self->outputbuffer;
......@@ -138,19 +85,19 @@ MessageRenderer_destroy(s_MessageRenderer* self) {
Py_TYPE(self)->tp_free(self);
}
static PyObject*
PyObject*
MessageRenderer_getData(s_MessageRenderer* self) {
return (Py_BuildValue("y#",
self->messagerenderer->getData(),
self->messagerenderer->getLength()));
}
static PyObject*
PyObject*
MessageRenderer_getLength(s_MessageRenderer* self) {
return (Py_BuildValue("I", self->messagerenderer->getLength()));
}
static PyObject*
PyObject*
MessageRenderer_isTruncated(s_MessageRenderer* self) {
if (self->messagerenderer->isTruncated()) {
Py_RETURN_TRUE;
......@@ -159,23 +106,23 @@ MessageRenderer_isTruncated(s_MessageRenderer* self) {
}
}
static PyObject*
PyObject*
MessageRenderer_getLengthLimit(s_MessageRenderer* self) {
return (Py_BuildValue("I", self->messagerenderer->getLengthLimit()));
}
static PyObject*
PyObject*
MessageRenderer_getCompressMode(s_MessageRenderer* self) {
return (Py_BuildValue("I", self->messagerenderer->getCompressMode()));
}
static PyObject*
PyObject*
MessageRenderer_setTruncated(s_MessageRenderer* self) {
self->messagerenderer->setTruncated();
Py_RETURN_NONE;
}
static PyObject*
PyObject*
MessageRenderer_setLengthLimit(s_MessageRenderer* self,
PyObject* args)
{
......@@ -195,7 +142,7 @@ MessageRenderer_setLengthLimit(s_MessageRenderer* self,
Py_RETURN_NONE;
}
static PyObject*
PyObject*
MessageRenderer_setCompressMode(s_MessageRenderer* self,
PyObject* args)
{
......@@ -220,14 +167,71 @@ MessageRenderer_setCompressMode(s_MessageRenderer* self,
}
}
static PyObject*
PyObject*
MessageRenderer_clear(s_MessageRenderer* self) {
self->messagerenderer->clear();
Py_RETURN_NONE;
}
} // end of unnamed namespace
// end of MessageRenderer
namespace isc {
namespace dns {
namespace python {
PyTypeObject messagerenderer_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"pydnspp.MessageRenderer",
sizeof(s_MessageRenderer), // tp_basicsize
0, // tp_itemsize
(destructor)MessageRenderer_destroy,// tp_dealloc
NULL, // tp_print
NULL, // tp_getattr
NULL, // tp_setattr
NULL, // tp_reserved
NULL, // tp_repr
NULL, // tp_as_number
NULL, // tp_as_sequence
NULL, // tp_as_mapping
NULL, // tp_hash
NULL, // tp_call
NULL, // tp_str
NULL, // tp_getattro
NULL, // tp_setattro
NULL, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"The MessageRenderer class encapsulates implementation details "
"of rendering a DNS message into a buffer in wire format. "
"In effect, it's simply responsible for name compression at least in the "
"current implementation. A MessageRenderer class object manages the "
"positions of names rendered in a buffer and uses that information to render "
"subsequent names with compression.",
NULL, // tp_traverse
NULL, // tp_clear
NULL, // tp_richcompare
0, // tp_weaklistoffset
NULL, // tp_iter
NULL, // tp_iternext
MessageRenderer_methods, // tp_methods
NULL, // tp_members
NULL, // tp_getset
NULL, // tp_base
NULL, // tp_dict
NULL, // tp_descr_get
NULL, // tp_descr_set
0, // tp_dictoffset
(initproc)MessageRenderer_init, // tp_init
NULL, // tp_alloc
PyType_GenericNew, // tp_new
NULL, // tp_free
NULL, // tp_is_gc
NULL, // tp_bases
NULL, // tp_mro
NULL, // tp_cache
NULL, // tp_subclasses
NULL, // tp_weaklist
NULL, // tp_del
0 // tp_version_tag
};
// Module Initialization, all statics are initialized here
bool
......@@ -260,5 +264,6 @@ initModulePart_MessageRenderer(PyObject* mod) {
return (true);
}
} // namespace python
} // namespace dns
} // namespace isc
// Copyright (C) 2011 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 __PYTHON_MESSAGERENDERER_H
#define __PYTHON_MESSAGERENDERER_H 1
#include <Python.h>
namespace isc {
namespace util {
class OutputBuffer;
}
namespace dns {
class MessageRenderer;
namespace python {
// The s_* Class simply covers one instantiation of the object.
//
// since we don't use *Buffer in the python version (but work with
// the already existing bytearray type where we use these custom buffers
// in C++, we need to keep track of one here.
class s_MessageRenderer : public PyObject {
public:
s_MessageRenderer();
isc::util::OutputBuffer* outputbuffer;
MessageRenderer* messagerenderer;
};
extern PyTypeObject messagerenderer_type;
bool initModulePart_MessageRenderer(PyObject* mod);
} // namespace python
} // namespace dns
} // namespace isc
#endif // __PYTHON_MESSAGERENDERER_H
// Local Variables:
// mode: c++
// End:
This diff is collapsed.
// Copyright (C) 2011 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 __PYTHON_NAME_H
#define __PYTHON_NAME_H 1
#include <Python.h>
#include <util/python/pycppwrapper_util.h>
namespace isc {
namespace dns {
class NameComparisonResult;
class Name;
namespace python {
//
// Declaration of the custom exceptions
// Initialization and addition of these go in the module init at the
// end
//
extern PyObject* po_EmptyLabel;
extern PyObject* po_TooLongName;
extern PyObject* po_TooLongLabel;
extern PyObject* po_BadLabelType;
extern PyObject* po_BadEscape;
extern PyObject* po_IncompleteName;
extern PyObject* po_InvalidBufferPosition;
extern PyObject* po_DNSMessageFORMERR;
//
// Declaration of enums
// Initialization and addition of these go in the module init at the
// end
//
extern PyObject* po_NameRelation;
// The s_* Class simply covers one instantiation of the object.
class s_NameComparisonResult : public PyObject {
public:
s_NameComparisonResult() : cppobj(NULL) {}
NameComparisonResult* cppobj;
};
class s_Name : public PyObject {
public:
s_Name() : cppobj(NULL) {}
Name* cppobj;
size_t position;
};
extern PyTypeObject name_comparison_result_type;
extern PyTypeObject name_type;
bool initModulePart_Name(PyObject* mod);
/// This is A simple shortcut to create a python Name object (in the
/// form of a pointer to PyObject) with minimal exception safety.
/// On success, it returns a valid pointer to PyObject with a reference
/// counter of 1; if something goes wrong it throws an exception (it never
/// returns a NULL pointer).
/// This function is expected to be called with in a try block
/// followed by necessary setup for python exception.
PyObject* createNameObject(const Name& source);
} // namespace python
} // namespace dns
} // namespace isc
#endif // __PYTHON_NAME_H
// Local Variables:
// mode: c++
// End:
......@@ -38,6 +38,14 @@
#include <dns/messagerenderer.h>
#include "pydnspp_common.h"
#include "messagerenderer_python.h"
#include "name_python.h"
#include "rcode_python.h"
#include "tsigkey_python.h"
#include "tsig_rdata_python.h"
#include "tsigerror_python.h"
#include "tsigrecord_python.h"
#include "tsig_python.h"
namespace isc {
namespace dns {
......@@ -52,14 +60,9 @@ PyObject* po_DNSMessageBADVERS;
}
}
#include "rcode_python.h"
#include "tsigerror_python.h"
// order is important here!
using namespace isc::dns::python;
#include <dns/python/messagerenderer_python.cc>
#include <dns/python/name_python.cc> // needs Messagerenderer
#include <dns/python/rrclass_python.cc> // needs Messagerenderer
#include <dns/python/rrtype_python.cc> // needs Messagerenderer
#include <dns/python/rrttl_python.cc> // needs Messagerenderer
......@@ -67,8 +70,6 @@ using namespace isc::dns::python;
#include <dns/python/rrset_python.cc> // needs Rdata, RRTTL
#include <dns/python/question_python.cc> // needs RRClass, RRType, RRTTL,
// Name
#include <dns/python/tsigkey_python.cc> // needs Name
#include <dns/python/tsig_python.cc> // needs tsigkey
#include <dns/python/opcode_python.cc>
#include <dns/python/edns_python.cc> // needs Messagerenderer, Rcode
#include <dns/python/message_python.cc> // needs RRset, Question
......@@ -167,14 +168,21 @@ PyInit_pydnspp(void) {
return (NULL);
}
if (!initModulePart_TSIG(mod)) {
return (NULL);
}
if (!initModulePart_TSIGError(mod)) {