BIND 10 #2414: Use AllocationEngine to actually handle v6 clients' messages
BIND 10 Development
do-not-reply at isc.org
Fri Nov 2 18:58:11 UTC 2012
#2414: Use AllocationEngine to actually handle v6 clients' messages
-------------------------------------+-------------------------------------
Reporter: tomek | Owner: stephen
Type: task | Status: reviewing
Priority: | Milestone: Sprint-
medium | DHCP-20121101
Component: dhcp6 | Resolution:
Keywords: | Sensitive: 0
Defect Severity: N/A | Sub-Project: DHCP
Feature Depending on Ticket: | Estimated Difficulty: 0
Add Hours to Ticket: 0 | Total Hours: 0
Internal?: 0 |
-------------------------------------+-------------------------------------
Changes (by tomek):
* owner: tomek => stephen
Comment:
Replying to [comment:5 stephen]:
> '''src/bin/dhcp6/dhcp6_messages.mes'''[[BR]]
> DHCP_DB_BACKEND_STARTED: Second sentence would probably be better
expressed as "It indicates what database backend is being used to store
lease and other information."
Done.
> DHCP_LEASE_ALLOC(_FAIL): is it possible to distinguish between the
advertised or allocated message - either by a different code or by means
of another field in the message?
Done. There are 4 messages now: DHCP6_LEASE_ADVERT(_FAIL) and
DHCP6_LEASE_ALLOC(_FAIL).
>
> DHCP6_SUBNET*: the message should start with a lower-case character.
I thought the the message is supposed to be a full English sentence
(starting with upper-case and ending with a dot). Anyway, did as you
asked. There were couple more messages that started with upper-case, so I
fixed them as well.
> DHCP6_SUBNET_SELECTION_FAILED: suggest:
> "This warning message is output when a packet was received from a subnet
for which the DHCPv6 server has not been configured. The cause is most
likely due to a misconfiguration of the server. The packet has been
ignored."
> (''Note - Is the last sentence true?'')
No. Server will include status-code option with code NoAddrsAvail and
continue processing the message. That behavior is enforced by RFC3315. It
is possible (but unlikely) that the same message may contain other options
that will be served (e.g. IA_PD or another IA_NA option).
On a side note, the getSubnet() method is very simple for now, but it will
become much more complex once we start supporting relays. Also, I have an
idea for very simple way of differentiating between interfaces (so the
user will be able to specify that subnet A should be served over eth0 and
subnet B over eth1).
> '''src/bin/dhcp6/dhcp6_srv.cc'''[[BR]]
> Dhcp6Srv constructor: Not clear about the comment "used for testing
purposes": that looks as if it should apply to the check of
"countIfaces()", not the check of "port".
Port 0 has special meaning - to not open sockets at all. Clarified the
comment.
> Dhcp6Srv constructor: "used for testing..." should be "Used for
testing".
Fixed.
> "if (port) {". As port is numeric, would prefer "if (port > 0) {".
Done.
>
> The comments should make it clear that the test usage is with the port
equal to zero.
Done.
> The "todo" indicates that the lease manager should be implemented at the
point of the "todo". But the code instantiates the memfile lease manage
later on - where is the correct position?
Removed that old @todo.
> run(): what is the timeout measured in?
I seconds. Expanded that comment.
>
> setServerID(): comment: the logical place to store this information is
the database.
In theory yes, but practice may suggest something else. A server is a
server, regardless of the database it is using. Server-Id should not
change even if you change backends. Storing the server duid in the backend
will cause the server to change identity if you change backends. There's
very specific text in RFC3315 that we will break with this behavior.
We could provide a way to kind of keep the data in sync, but that will get
us into a completely new topic of data migration (and even worse, possible
synchronization) between backends. So yes - I agree with you in principle,
but that is not as simple as it looks.
> setServerID(): comments should start with a capital letter.
Fixed.
> setServerID(): "&srvid[0]+8" should be "&srvid[0] + 8".
Done.
>
> setServerID(): call to fillrandom() should have a space after the comma.
Done.
>
> copyDefaultOptions: use the "!OptionPtr" typedef instead of the explicit
type of boost::shared_ptr<Option>. (Incidentally, both addOption() methods
expect the argument to be passed by value, not reference: this will incur
the overhead of incrementing and decrementing the reference count of the
pointed-to object.)
>
> addRequestedOptions: use the "!OptionPtr" typedef instead of the
explicit type of boost::shared_ptr<Option>.
This code predates the OptionPtr definition. Updated.
>
> handleIA_NA: need more comments to explain what is happening.
Added more comments.
>
> assignLeases: need more comments to explain what is happening.
Added more comments.
> processXXX: a copy why "copyDefaultOptions" is immediately followed by
"appendDefaultOptions" (which from their names, appear to add two sets of
default options to the created packet) would be helpful.
The server's response contains many options. Some of them are copied from
client request (copyDefaultOptions, e.g. client-id) and some are always
inserted by the server (appendDefaultOptions, e.g. server-id or
preference). In both cases, client does not have to request it in any way
(on ORO), so in that sense they are default (options that must be sent by
default). There are also other options that are sent back only if
requested (appendRequestedOptions method).
That's the theory. In practice, the lines between them will be blurred, as
Marcin implements mechanism for sending options even if they are not
requested by clients. Once we add relay support, there will be other
things like ERO (echo request option), where relay asks server to send a
relay option back to the client. I think it should be rethinked, but not
as part of this ticket.
> '''src/bin/dhcp6/dhcp6_srv.h'''[[BR]]
> Trivial point: start all "@brief" descriptions with a capital letter.
Done.
>
> selectSubnet: need "@param" describing the "question" argument.
Done.
> '''src/bin/dhcp6/tests/dhcp6_srv_unittest.cc'''[[BR]]
> Would appreciate some documentation about the methods of the
Dhcp6SrvTest class (i.e. they should include a header, although perhaps
not a Doxygen one.)
>
> A number of the tests have identical function headers.
Most of them were similar (no hint sent, valid hint, invalid hint), but in
one instance it was an identical copy. Fixed.
> Solicit tests: is it worth checking that a sequence of solicit messages
result in advertise responses with different addresses?
It makes perfect sense. It also makes sense to implement similar test for
request. See new tests: ManySolicits and ManyRequests.
> '''src/lib/dhcp/Makefile.am'''[[BR]]
> OK. The memfile backend is probably better put in the main dhcp
directory (with appropriate "TODO"s about not being finished.)
Done. Added a text to memfile_LeaseMgr constructor that warns about
memfile being incomplete.
I have noted that there is some dependency between b10-dhcp++ and
b10-dhcpsrv libraries. It fails to build occasionally with: make -j8 (I
use 8 cores). After couple retries it finally builds. We should move
libdhcpsrv to separate directory.
> '''src/lib/dhcp/addr_utilities.cc'''[[BR]]
> {first,last}AddrInPrefix4() already have a check for prefix length.
(Although it should precede the assignment of the "addr" variable - which
is redundant if the exception is thrown - and there should be a space
around the ">" in lastAddrInPrefix4.) For this reason, I suggest the
prefix lengths checks be removed from {first,last}!AddrInPrefix(), and
checks added to the V6 versions (remembering to put spaces around the ">"
in the comparison).
Done.
> '''src/lib/dhcp/cfgmgr.cc'''[[BR]]
> getSubnet6(): Spurious space "if ( (subnets6_.size()...": there should
be no space between the two opening parentheses.
Fixed.
> getSubnet6(): I think we've discussed this before, but what happens if
the user has a configured subnet that does not match the configured single
pool? The logic here is that the single subnet is always chosen. Also,
suppose that there is a single V6 subnet that is not link local: it is
rejected by the first check but could still be chosen in the subsequent
iteration over the (single) subnet.
The current code in this regard is very simplified. Currently we support
only direct (not relayed) traffic, we don't differentiate between
interfaces and we don't support shared subnets. That means that we always
handle only a single subnet and the client's source address is always
link-local (fe80::/10).
> '''src/lib/dhcp/duid.cc'''[[BR]]
> toText(): For consistency, either set the string stream's fill
character, field width and output base with calls to "fill()", "width()",
and "setf()" before the loop, or set them on a per-output call inside the
loop with the manipulators hex, setfill and setw.
They cannot be set before the loop, as width() and setfill() operators
affect only the next token, not the whole stream. Hex manipulator on the
other hand, affects the whole stream, so it is now done before the loop
(no need to repeat it).
> '''src/lib/dhcp/duid.h'''[[BR]]
> It is not usual to write "operator==()" as "operator == ()" (same goes
for the "not equals" operator.)
Fixed.
> ''' src/lib/dhcp/subnet.h'''[[BR]]
> get(): it is probably clearer to use the "make_pair" call:
> {{{
> std::pair<isc::asiolink::IOAddress, uint8_t> get() const {
> return (std::make_pair(prefix_, prefix_len_));
> }
> }}}
> (Also note that "get()" can be declared "const").
Done.
> toText(): this can be declared "const".
Done.
> '''src/lib/dhcp/tests/duid_unittest.cc'''[[BR]]
> toText() test: there is no need to create a DUID via "new" or used a
scoped pointer to store it: it could be created as an automatic variable:
> {{{
> DUID duid1(data1, sizeof(data1));
> EXPECT_EQ("00:01:02:03:04:ff:fe", duid1.toText());
> }}}
Done.
> '''src/lib/dhcp/tests/lease_mgr_unittest.cc'''[[BR]]
> OK. (Looks as if I need to complete all the xxx6() methods in the MySQL
lease manager code for it to be useful.)
I'm not sure about that. Originally memfile was planned as way to test
LeaseMgr interface, so those tests may continue to use memfile backend.
IIRC you have developed dedicated tests to MySQL backend.
> '''src/lib/dhcp/tests/subnet_unittest.cc'''[[BR]]
> toText() test: there is no need to create a Subnet4 via "new" or used a
scoped pointer to store it: it could be created as an automatic variable.
(See comment for duid_unittest.cc.)
I've converted some of the tests. Tests don't have to be consistent. In
fact, variety of approaches should be preferred to test them. You can
consider some of the tests as implicit test for Subnet6Ptr type. If the
shared_ptr fails to release the object, we will fail valgrind.
Changes pushed. The ticket is back with you. I will have some spare cycles
during IETF, but I would very much prefer to do non-critical things, as
there may be folks hunting for me for IETF things.
--
Ticket URL: <http://bind10.isc.org/ticket/2414#comment:6>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list