[kea-dev] Strange behaviour with Option 53 - what am I missing?

Dave Cole davecole at nbnco.com.au
Tue Jan 30 00:45:12 UTC 2018


I have decided that before publishing my Python bindings I should add a bunch of unit tests.  In the process I discovered something strange:

>>> from kea import *
>>> p = Pkt4(DHCPDISCOVER, 0)
>>> o = p.getOptions()[DHO_DHCP_MESSAGE_TYPE]
>>> o.getUint8()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Attempt to read uint8 from option 53 that has size 0
>>> o.getString()
'\x01'

The implementation of getUint8 is:

static PyObject *
Option_getUint8(OptionObj *self, PyObject *args) {
    try {
        return (PyInt_FromLong(self->option_ptr->getUint8()));
    } catch (const exception &e) {
        return (raisePythonError(PyExc_TypeError, e.what()));
    }
}

Whereas the getString is:

static PyObject *
Option_getString(OptionObj *self, PyObject *args) {
    try {
        vector<uint8_t> value = self->option_ptr->toBinary();
        return (PyString_FromStringAndSize((const char *) &value[0], value.size()));
    } catch (const exception &e) {
        return (raisePythonError(PyExc_TypeError, e.what()));
    }
}

So when I step through the code with gdb it appears that DHO_DHCP_MESSAGE_TYPE is an instance of OptionInt which does not use the data_ member of Option, instead it has another member value_ of the type defined in the template argument.

Is it a deliberate choice in the code to require application code to just know that getUint8 does not work for OptionInt (which subclasses Option)?

Someone with more of a clue about c++ than me might be able to tell me an easy (and efficient) way I can make my code notice an OptionInt and internally use getValue() rather than getUint8().  Would a dynamic_pointer_cast<OptionUint8>(self->option_ptr) be the way to go?


More information about the kea-dev mailing list