]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[fdxhook] Fixed memory management and added NOTES files
authorFrancis Dupont <fdupont@isc.org>
Thu, 16 Jun 2016 15:52:46 +0000 (17:52 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 16 Jun 2016 15:52:46 +0000 (17:52 +0200)
src/hooks/external/NOTES [new file with mode: 0644]
src/hooks/external/python/NOTES [new file with mode: 0644]
src/hooks/external/python/dso.cc
src/hooks/external/python/poption.cc
src/hooks/external/python/ppkt4.cc

diff --git a/src/hooks/external/NOTES b/src/hooks/external/NOTES
new file mode 100644 (file)
index 0000000..cc8bf3b
--- /dev/null
@@ -0,0 +1,56 @@
+Kea hooks in external (i.e., not C++) languages.
+
+Asked for customers: hooks written in python (see below), lua,
+ocaml (see below?), ...
+
+Kea hook summary:
+ - dynamic shared objects loaded from the config on hooks-libraries
+
+ - version (against binary API mismatch), load and unload entry points
+
+ - callouts for Kea -call-> external code -return-> Kea interaction,
+  registered by load, using an API to access arguments, context and result
+
+ - standard hook points in packet processing (aka Kea service loop)
+
+Question: which entity is embedded?
+Answer: the external language (e.g. python, ocaml) is embedded
+ (cf https://docs.python.org/3/extending/embedding.html and
+  http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#sec432)
+
+Question: when initializes the external language?
+Answer: in the DSO load (cf Py_Initialize()) (and unload should
+finalize, cf Py_Finalize())
+
+Question: what to call from callouts in the external language?
+Answer: a routine getting one argument selecting the called hook
+
+Question: how to build?
+Answer: for python use python-config
+
+Question: what C++ object to translate?
+Answer: packet, option (in fact every thing from the management API) and
+element (for config), imported as external pointers and using set/get
+C++ methods, and of course callout tools (including exceptions)
+
+Question: and lua?
+Answer: C++ objects map to lua full userdata by default
+(cf http://www.troubleshooters.com/codecorn/lua/lua_c_calls_lua.htm ?)
+(doc at https://www.lua.org/docs.html but not very useful,
+ https://www.lua.org/pil/p1.html is obsolete but better)
+
+Question: C++ shared_ptr?
+Answer: must use explicit finalization to reset shared_ptr's
+
+Question: DHCPv4 packet example?
+Answer: Pkt4Ptr with addOption, getCiaddr, getHtype, getHWAddr,
+ getType, toText, (inherit) getIface, getOption, getTimestamp, ...
+
+Question: (generic) option example?
+Answer: OptionPtr with (class) factory, getData, getType, len, toText, ...
+
+Question: external language types?
+Answer:
+ python3: int, float, str, bytes
+ ocaml: int, float, string (include binary)
+ lua: (number) integer, (number) float, string (include binary)
diff --git a/src/hooks/external/python/NOTES b/src/hooks/external/python/NOTES
new file mode 100644 (file)
index 0000000..d6dd981
--- /dev/null
@@ -0,0 +1,50 @@
+Implementation notes fro python
+
+Manifest:
+ - poption.h poption.cc: the C++ OptionPtr encapsulated into a python
+  object with some methods ported.
+
+ - ppkt4.h ppkt4.cc: the C++ Pkt4Ptr encapsulated into a python object
+  with some methods ported. Note there is no constructor in python.
+
+  one can complete these python types or/and new python type.
+
+ - module.h module.cc: the python kea module. Initialization only (of
+  the module and option+pkt4 types), no module method (aka function)
+  nor object (constant).
+
+ - dso.cc: the kea framework and hook glue: on the kea / C side it is
+  a dynamic shared object providing the framework and hook entry points,
+  on the python side it embbeds an interpreter which imports the
+  python script hook.py.
+
+  poption.o, ppkt4.o, module.o and dso.o are compiled into kea.so.
+
+ - hook.py: the python script which implements the python part of
+  hook handlers using the python kea module.
+
+ - tests.cc: source of test program which loads the kea.so hook-library
+  and exercise the pkt4_receive hook. It gives an independent executable.
+
+ - cshenv: C-shell script setting environment variables for a kea
+  distrib in /tmp/kea on OS X.
+
+ - Makefile: make config file for OS X.
+
+ - NOTES: this file.
+
+Some hairy points (not particular to python but found with it):
+ - the hardest is to build a working Makefile in particular for this system
+
+ - hooks must be registered as soon as possible (kea-dhcp* do this
+  in the global initialization)
+
+ - initLogger() must be soon too (kea-dhcp* do it through
+  Daemon::loggerInit() just after command line argument parsing
+
+ - there is no easy way to know if hook libraries were successfully
+  loaded?
+
+ - be very careful with external language memory management
+  (they provide a garbage collector which is very fine inside the
+   language but can become hairy for the C++ interface)
index a10f938f781892e9e13fa8a4c0d5cb926d1abb26..4a5acdf4f719b8e077da59fee2f7c7d9c6519eb3 100644 (file)
@@ -138,6 +138,7 @@ int pkt4_receive(CalloutHandle& handle) {
     (static_cast<py_pkt4*>(query))->object = query4;
 
     PyObject* args = Py_BuildValue("(O)", query);
+    Py_DECREF(query);
     if (!args) {
         PyErr_Print();
         cerr << "Py_BuildValue failed\n";
index bf1c4163792865b14ee16dc58ce280874faf8abe..9c5846106b348551adbd4872b243ef562503c017 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <hooks/external/python/poption.h>
 
+#include <iostream>
+
 using namespace std;
 using namespace isc::dhcp;
 using namespace isc::python;
@@ -62,6 +64,8 @@ option_init(PyObject* obj, PyObject* args, PyObject*) {
 // tp_dealloc
 void
 option_dealloc(PyObject* obj) {
+    // This is a critical code to avoid memory leaks
+    cout << "option_dealloc called\n";
     py_option* const self = static_cast<py_option*>(obj);
     self->object.reset();
     Py_TYPE(self)->tp_free(self);
index d891f52233bc05936d9fc05a9b8afbde7a72f164..bdad7d5327f18e063eec77b26cc40aebf0f6285f 100644 (file)
@@ -10,6 +10,8 @@
 #include <hooks/external/python/poption.h>
 #include <hooks/external/python/ppkt4.h>
 
+#include <iostream>
+
 using namespace std;
 using namespace isc::dhcp;
 using namespace isc::python;
@@ -30,6 +32,8 @@ pkt4_init(PyObject*, PyObject*, PyObject*) {
 // tp_dealloc
 void
 pkt4_dealloc(PyObject* obj) {
+    // This is a critical code to avoid memory leaks
+    cout << "pkt4_dealloc called\n";
     py_pkt4* const self = static_cast<py_pkt4*>(obj);
     self->object.reset();
     Py_TYPE(self)->tp_free(self);