BIND 10 #2312: Custom Option implementation
BIND 10 Development
do-not-reply at isc.org
Wed Nov 28 17:11:40 UTC 2012
#2312: Custom Option implementation
-------------------------------------+-------------------------------------
Reporter: | Owner: stephen
marcin | Status: reviewing
Type: task | Milestone: Sprint-
Priority: | DHCP-20121129
medium | Resolution:
Component: dhcp | Sensitive: 0
Keywords: | Sub-Project: DHCP
Defect Severity: | Estimated Difficulty: 0
Medium | Total Hours: 0
Feature Depending on Ticket: |
Add Hours to Ticket: 0 |
Internal?: 0 |
-------------------------------------+-------------------------------------
Changes (by marcin):
* owner: marcin => stephen
Comment:
Replying to [comment:7 stephen]:
> Reviewed commit 863da09e4d4ef50693860dd95948ae5171ba5116
>
> '''General'''[[BR]]
> I've corrected a few typos and missing Doxygen keywords, and pushed the
modified files back to the repository.
Ok. Thanks!
>
> '''src/lib/dhcp/option_custom.h'''[[BR]]
> !OptionCustom constructors: If !OptionCustom is used by the server, then
supplying iterators to the first and last elements that should be copied
as constructor arguments seems to assume that I know the data and that
data is going to be sent. However, the header indicates that that data
supplied to the constructor in this manner is used for received options.
A bit more explanation would be helpful.
I updated the doxygen comments and I am hoping now it is clearer.
>
> readAddress(): more a question of style, but wouldn't it be more logical
to have readAddress return an IOAddress through the return value rather
than passing back through an already-created IOAddress object?
I thought that it is better to avoid additional copy construction of the
object but finally
I decided to follow your suggestion for consistency and ease of use.
>
> readString(): would it be better to return the string through the
function return value?
Same as above.
>
> '''src/lib/dhcp/option_custom.cc'''[[BR]]
> Constructors: looking at the definition of the constructors, they appear
more or less equivalent. In which case, how is the send/receive
distinction referred to in the header comments (in the .h file) justified?
As I mentioned above. I have put some additional comment in a header file.
>
> createBuffers() (line 103): the comments does not make sense.
I updated the comment. Hopefully it has more sense now.
>
> createBuffers() (line 129): at the end of the do...while loop, no
exception is thrown if the data is truncated. However, an exception is
thrown in other places where data is truncated.
I assume that a buffer is truncated to create an option with array of
values if you can't make at least one valid value out of it. Otherwise it
is ok that the buffer length is not divisible by the size of the element.
The remaining part is ignored by intent.
>
> createBuffer() (line 134-136): This is a no-op if the data type is
OPT_EMPTY_TYPE. It would be logical to put this check (and the following
if/else clause at lines 136-140) within a check of data_type.
Ok. Instead of putting it on the beginning I changed the global if
statements so as they exclude OPT_EMPTY_TYPE. That's pretty much the same
but there was no sense to create if statement for no-op.
>
> pack4()/pack6(): are we sure that an !OptionBuffer can't be empty? If
it is, then the reference to (*it)[0] could be invalid.
In theory it shouldn't because it is being validated by createBuffers but
... I added a check to be sure.
>
> dataFieldToText()/toText(): would prefer that the string stream variable
be named something like "text" than "tmp". "tmp" tends to be used in
throwaway code or in situations where a variable is needed for a couple of
lines. This variable persists through the entire method.
Renamed.
>
> toText(): I suggest removing the "= 0" in the parameter list. The
default value of the "indent" parameter does not affect the operation of
the method.
Removed as it was copied from option.cc implementation. However I am not
exactly sure your motivation to remove it. IMHO, It does affect the
operation of the method because the text will be printed out in a
different position.
>
> '''option_data_types.h'''[[BR]]
> !OptionDataTypeUtil: Suggest that the class header include an
explanation that the class is a singleton, but is only accessed through
static class methods.
Added.
>
> readAddress(): would not this be better returning an IOAddress through
the function return value?
Already discussed above.
>
> writeXxxx(): The header comments should make it clear that these methods
append the data to the end of the passed buffer rather than overwriting
the entire buffer.
Added.
>
> writeInt(): should add a comment about converting to an unsigned integer
will be OK even for signed types.
Added in the function body.
>
> readString(): why not return a std::string as much of the rest of the
BIND 10 code does in similar situations?
Discussed above.
>
> '''src/lib/dhcp/option_data_types.cc'''[[BR]]
> !OptionDataTypeUtil constructor: there is a mapping for OPT_UNKNOWN_TYPE
-> "unknown", but not vice-versa.
That is ok. I added a comment to explain why.
>
> getDataTypeLen(): suggest adding a blank line before each set of "case"
statements (apart from the first) - it looks clearer.
Added.
>
> readAddress(): error at line 124 - the check should be "else if (family
== AF_INET6)"
Added.
>
> writeAddress(): The functionality of converting an IP address to a
string of bytes really belongs in the IOAddress class. We already have a
ticket for this - #2396, which adds an "IOAddress::toBytes()" method.
Once this is done, writeAddress() becomes relatively trivial. I suggest
we add #2396 to the sprint, implement that, then use it in this method.
That functionality will be useful indeed to simplify this method. However
I don't want to rely on #2396 to merge this code to master so I added todo
statement and once this function is implemented it can be changed.
>
> writeBool(): This could be simplified to a single line:
> {{{
> buf.push_back(static_cast<uint8_t>(value ? 1 : 0));
> }}}
Changed.
>
> readString()/writeString(): these are essentially doing the same task
(appending an array of bytes to another array) but are doing it in
different ways. They should be consistent.
They are now consistent.
>
> '''src/lib/dhcp/option_definition.cc'''[[BR]]
> addRecordField() (line 68): as the code is making an assumption about
the ordering of the OPT_xxx symbols (i.e. that there are no simply types
with a value higher than OPT_RECORD_TYPE), a comment to that effect should
be added to the defintion of !OptionDataType in option_data_types.h.
I added a comment.
>
> writeToBuffer() (line 352 on): suggest using IOAddress::getFamily()
rather than extracting the underlying asio::ip address type.
(Alternatively, #2396 could be extended to add isV4() and isV6() methods
to IOAddress.)
I am now using getFamily function.
>
> '''src/lib/dhcp/tests/option_custom_unittest.cc'''[[BR]]
>
> All tests for different data types should include a check that an
exception is thrown if the buffer is too short. (It's done in a couple of
places, but not everywhere - e.g. checking that the parsing of a V6
address will thrown the exception if the buffer is too short).
I added checks in every test case.
>
> ipv4AddressDataArray test (line 487): not sure why the end is written as
"buf.begin() + 13" instead of buf.end(). (Similar comment in the
ipv6AddressDataArray test.) Both tests should also check what happens if
the array size is not a multiple of the address size - does it throw a
"data truncated" exception?
>
Yes, this is an error. I now use the constructor that takes whole buffer
rather than a pair of iterators. I use a pair of iterators when I want to
simulate truncated buffer.
The proposed ChangeLog entry:
{{{
XXX. [func] marcin
Implemented an OptionCustom class for DHCPv4 and DHCPv6.
This class represents an option which has a defined
structure: set of data fields of specific types and order.
Those fields can be accessed using indexes, where index 0
represents first data field and index equal to 'number
of fields' - 1 represents the last data field. This class
is used to represent those options that can't be represented
by any other specialized class.
(Trac #2312, git ...)
}}}
--
Ticket URL: <http://bind10.isc.org/ticket/2312#comment:8>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list