BIND 10 #1186: libdhcp implementation - DHCPv6 part
BIND 10 Development
do-not-reply at isc.org
Wed Oct 12 09:36:26 UTC 2011
#1186: libdhcp implementation - DHCPv6 part
-------------------------------------+-------------------------------------
Reporter: tomek | Owner: tomek
Type: | Status: reviewing
enhancement | Milestone: Sprint-
Priority: major | DHCP-20111011
Component: dhcp | Resolution:
Keywords: | Sensitive: 0
Defect Severity: N/A | Sub-Project: DHCP
Feature Depending on Ticket: 878 | Estimated Difficulty: 0
Add Hours to Ticket: 0 | Total Hours: 0
Internal?: 0 |
-------------------------------------+-------------------------------------
Comment (by tomek):
Replying to [comment:5 stephen]:
> = Review of commit f56892b514cedb0538c37db808ec543d7a4fcfaf - part 2 =
>
> Would suggest that the typedefs OptionXCollection (instead of
OptionXLst) be used, as a "Lst" suffix implies a list.
Renamed.
> All method declarations - including constructors - should have full
Doxygen headers.
Documented.
> unpack(): given that the option data in the buffer includes a length
field that is the length of the option data, does unpack() really need the
parse_len option?
Yes. Because sometimes only certain size of the buffer needs to be parsed.
One notable example is when you parse an option that contains suboptions.
You don't want to parse till end of the buffer, but just a specific
length. That length is obtained when parsing upper level option, so it
cannot be derived here. Therefore needs to be passed as a parameter.
> unpack(): Offsets into the buffer (and buffer sizes) should be size_t
instead of "unsigned int".
Agree. This also applies to many other method and code pieces throughout
the whole libdhcp and dhcp6. Added ticket #1295 for that.
> toText(): no other toText() method in BIND 10 takes an indentation
argument.
That implies that no other code in BIND10 deals with nested options. The
idea here is that for nested options, each option will be printed indented
for clearer representation. I understand that it is a new concept, so the
default value of indent parameter is 0. The usual usage stays the same.
> addOption(): shared pointer should be passed by reference (to avoid a
needless copy when passed by value).
Certainly not. That is where copy or shared pointer is needed. One option
(e.g. server-id) may be added in many places, yet due to shared pointer
only one instance will be created.
> getOption()/delOption() should be renamed getSubOption()/delSubOption().
I would prefer to keep it as getOption/delOption. This way, regardless of
the object (a packet, an option or a cache), the same method can be used
(getOption). A shorter names are easier to type.
> Related to suboptions: would it be better for the Option class to supply
an iterator (and associated begin()/end()) methods to allow iterations
over suboptions contained within an option? That way, all STL algorithms
could be used on the suboption collection.
That is a useful suggestion, but it is not that straightforward. If
iterator is provided and someone modifies content of said option (e.g.
adds new suboption) this iterator may become invalid. Having said that,
getOption(int type) is very convenient. It must stay as it is. Added
ticket #1296 for iterator work.
> pack4()/pack6() - see suggestion about two Option classes, one for V4
and one for V6.
Added to ticket #1295.
> What is optionLst_?
A collection of options. Renamed to options_ and added doxygen comment.
> Is there any reason why the data members are protected instead of
private?
Yes. They are expected to be used in tests.
> '''src/lib/dhcp/option.cc'''[[BR]]
> pack6()/pack6(): use of an !OutputBuffer will automatically take care of
extending the buffer as needed.
Calling realloc() many times is less optimal than calculating length and
then doing a single new (Pkt6 approach).
> pack4(): not clear why data_len_+4 bytes are being copied into the
output buffer. The type and length have already been copied and the
pointer into the buffer advanced. According to the comment in the header
file, data_len_ is the length of data only, so copying data_len_+4 risks
copying beyond the allocated data area. (Note that only data_len_ bytes
are copied in pack6().)
That was a bug. Fixed. The reason why this wasn't caught is that work on
v4 is not really started yet. Very small number of v4 functions were
implemented to see if the design is feasible. Proper implementation and
testing will commence once this ticket is resolved.
> len(): need comment as to why the length is increments by the length of
the contents of optionLst_. I am assuming that these are suboptions, but
there is nothing here or in the header file to indicate that.
Commented how and why specific values are included in len().
> valid(): the comments here do not relate to the code.
Removed.
> valid(): A simpler statement is {{{return ((universe == V4) || (universe
== V6));}}}.
>
> valid(): Under what circumstances (other than wrong universe) can an
option be invalid?
This implementation is simple for now, but there is potential for growth
here. Note that this is a virtual method, so derived classes may do
additional checks, e.g. length of address list type of options may check
if their length is divisible by 16. Some checks may be a bit more subtle,
e.g. even though FQDN is encoded properly it may still be invalid (e.g.
contain a single label).
Now, for the base Option class this method is also expected to be
expanded. We may decide to have a table with option types and required
lengths (many options). We may expand this into passing message type and
then checking if option is allowed to appear in specific message type. The
same holds true for suboptions. Some options are allowed to appear only
within specific other options etc.
This method will definitely grow.
> addOption(): argument should be passed by reference.
No, see above comment.
> getOption()/delOption(): should be spaces around the "!=".
Done.
> delOption(): the intended result of the method is that after execution,
the specified option is not in the collection. If it wasn't there to
begin with, after the method call the result is the same, the option is
not there. In this case, is it justified to return false? A second
question is, if this is an unexpected occurrence, isn't throwing an
exception the better way of signalling it?
It's not unexpected. It is faster to try to delete option and check if
deletion was successful than search for an option and if it's there,
delete it. Both approaches are equally fast in negative case (no option
present), but using delOption() is twice as fast in positive case (there's
option to be deleted). No exceptions necessary.
> '''src/lib/dhcp/option6_addrlst.h'''[[BR]]
> In the typedef, suggest that !AddressContainer is easier to read than
!AddrsContainer. (The latter only saves two characters.)
Done.
> In the constructors, the address(es) should be passed as const.
Done.
> In the simplified constructor, the single address should be passed by
reference.
Done.
> In the constructor for parsing the received option (and in both pack()
and unpack()), "buf" should be passed by reference.
No. This buffer should be kept around for until this option is valid.
Passing shared pointer be reference is valid only for pure consumers. That
is clearly not the case here.
> In setAddress(), the argument should be passed by reference and should
be const.
Done.
> In setAddresses(), the argument should be const.
Done.
> '''src/lib/dhcp/option6_addrlst.cc'''
> Constructor taking a vector: addrs_ can be initialised in the member
variable initializer list with {{{addrs_(addrs)}}}.
>
> Constructor taking a single IOAddress: addrs_ can be initialized in the
member variable initialiser list with {{{addrs_(1, addrs)}}}.
That's a nice trick. I didn't know that.
> pack()/unpack(): use of "magic number" of 16. Better is to use a named
constant.
After couple of minutes of digging around and failing to find already
defined constant, I added a new one. Once I find where it is already
defined, I'll replace it.
> toText(): would suggest that this method just returns the addresses as a
simple space-separated list. This will make it easier to use in log
messages and other places where a list is required.
toText() is currently used to print out details of incoming and outgoing
packets. I agree that shorter form is useful as well. If that is common
practice in BIND10 for functions toText() to return short version, so be
it. Full text is useful as well. This is generic problem for all classes.
Added ticket #1297.
> len(): suggest that the DHCPv6 option header length is defined as a
constant somewhere.
Added.
Commit-id: 2894b07900ec81ed39284c7d7df5660eb8afbfc0 (part 5 of review
changes).
--
Ticket URL: <http://bind10.isc.org/ticket/1186#comment:9>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list