<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">I now have my module at the point where I can use a pcap file from the live network in Python unit tests to regression test the Python code loaded in Kea.  Happy days.</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">I hope I get permission to release this stuff.</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> kea-dev <kea-dev-bounces@lists.isc.org> on behalf of Dave Cole <davecole@nbnco.com.au><br>
<b>Sent:</b> Tuesday, 23 January 2018 9:32:28 AM<br>
<b>To:</b> Francis Dupont<br>
<b>Cc:</b> kea-dev@lists.isc.org<br>
<b>Subject:</b> Re: [kea-dev] Kea python hook?</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Sorry about the quoting style - I am forced to use LookOut here...<br>
<br>
> Dave Cole writes:<br>
> > I did not know that code existed!<br>
> <br>
> => it had 2 purposes:<br>
>  - show it is possible to write a hook in a script language vs requiring C++<br>
>   with examples in Python, Lua, OCaml and v8<br>
<br>
My first attempt at embedding an interpreter here was with Lua.<br>
I gave up on that when I realised the poor quality of the 3rd<br>
party modules we had to use to implement our requirements<br>
<br>
>  - detail technical points so someone who wants to do the same thing<br>
>   can win a lot of time<br>
<br>
> On big difference in approach is that the code you have created<br>
> will not work with current Kea if the Python code imports a<br>
> module with native code - unless you statically link your code<br>
> with Kea.  Kea loads hooks with RTLD_LOCAL which prevents symbols<br>
> in the hook being visible in subsequent dynamic linking.  The<br>
> hook I created here connects to a database and publishes to Kafka<br>
> - we need to load native modules.<br>
<br>
> => currently hooks are dynamic shared objects which don't load<br>
> other DSOs and have no dependency between hooks, so RTLD_LOCAL<br>
> is enough. As it works for almost all cases and is simpler / faster<br>
> I believe it will stay the default but you can open a ticket asking<br>
> for a configure option to change it for RTLD_GLOBAL. If you provide<br>
> a pair of DSOs, one behaving as a hook and loading the second, for<br>
> unit tests, or pull a request on github, it will help because as<br>
> you know we have limited man power.<br>
<br>
I implement my hook with a Kea loaded DSO.  This does as little<br>
as possible due to the RTLD_LOCAL limitation.  It just<br>
initialises the Python interpreter then loads the kea extension<br>
module via Python import.  Inside the Python module is a Capsule<br>
containing endpoints for bootstrapping the Kea/Python binding.<br>
<br>
The advantage to this is I can move all of the Kea code into a<br>
kea module which you can then load from the Python command line.<br>
>From that point you are free to use plain Python code for things<br>
like unit tests.  I am working towards a public release of the<br>
code as my boss is actively seeking permission to release it.<br>
<br>
I want to get to the point where I can use pcap files for<br>
regression tests of my complex hook.  It is getting close.  For<br>
example:<br>
<br>
- - 8< - - - - - - - - - - - - - - - - - - - - - - - - - - -<br>
from kea import *<br>
<br>
trans_id = 0x50ea1f55<br>
<br>
p = Pkt4(DHCPDISCOVER, trans_id)<br>
p.setGiaddr('11.0.0.1')<br>
p.setHWAddr('02:42:ac:14:00:05')<br>
p.addOption(Option(DHO_DHCP_PARAMETER_REQUEST_LIST)<br>
            .setString(chr(DHO_SUBNET_MASK)<br>
                       + chr(DHO_BROADCAST_ADDRESS)<br>
                       + chr(DHO_ROUTERS)<br>
                       + chr(DHO_DOMAIN_NAME)<br>
                       + chr(DHO_DOMAIN_NAME_SERVERS)))<br>
o = Option(DHO_DHCP_AGENT_OPTIONS)<br>
o.addOption(Option(1).setString('Relay Agent Option 1'))<br>
o.addOption(Option(2).setString('Another Option'))<br>
p.addOption(o)<br>
p.pack()<br>
raw = p.getBuffer()<br>
<br>
r = Pkt4(raw)<br>
r.unpack()<br>
assert r.getType() == DHCPDISCOVER<br>
assert r.getTransid() == trans_id<br>
assert r.getGiaddr() == '11.0.0.1'<br>
assert r.getHWAddr() == '02:42:ac:14:00:05'<br>
assert r.getOption(DHO_DHCP_PARAMETER_REQUEST_LIST) \<br>
           .getString() == (chr(DHO_SUBNET_MASK)<br>
                            + chr(DHO_BROADCAST_ADDRESS)<br>
                            + chr(DHO_ROUTERS)<br>
                            + chr(DHO_DOMAIN_NAME)<br>
                            + chr(DHO_DOMAIN_NAME_SERVERS))<br>
o = r.getOption(DHO_DHCP_AGENT_OPTIONS).getOptions()<br>
assert o[1].getString() == 'Relay Agent Option 1'<br>
assert o[2].getString() == 'Another Option'<br>
- - 8< - - - - - - - - - - - - - - - - - - - - - - - - - - -<br>
<br>
> > Another thing I am confused about in your code is that you do not<br>
> > appear to do any exception handling.  If Python code calls Kea<br>
> > and an exception is raised, then the Python interpreter will get<br>
> > corrupted.<br>
> <br>
> => I mention exceptions in the doc as one of the things which should<br>
> be implemented. Of course it is simpler if the C++ code called<br>
> from the external language does not raise exceptions (*) so<br>
> you don't have to add a handler to stop stack unwinding.<br>
<br>
I found that out the hard way :-).<br>
_______________________________________________<br>
kea-dev mailing list<br>
kea-dev@lists.isc.org<br>
<a href="https://lists.isc.org/mailman/listinfo/kea-dev">https://lists.isc.org/mailman/listinfo/kea-dev</a><br>
</div>
</span></font></div>
</body>
</html>