BIND 10 #1230: V4 state machine - respond to DISCOVER packets
BIND 10 Development
do-not-reply at isc.org
Tue Dec 27 11:21:50 UTC 2011
#1230: V4 state machine - respond to DISCOVER packets
-------------------------------------+-------------------------------------
Reporter: | Owner: tomek
stephen | Status: accepted
Type: task | Milestone: Sprint-
Priority: major | DHCP-20111230
Component: dhcp4 | 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 |
-------------------------------------+-------------------------------------
Comment (by tomek):
Replying to [comment:4 stephen]:
> Reviewing changes from f60bf56ebed7189ad71d6c4ed4044d97b5e5c7a5
> to 01a1b2f4d210c62fc1d7a9b53e7967057e93d331
>
> '''src/bin/dhcp4/dhcp4_srv.cc'''[[BR]]
> Unless there is some reason not to, suggest you use IPv4 addresses in
the range 192.0.2.0/24 and domain names such as example.com, as per the
coding guidelines. (In particular, the hardcoded DNS servers and domain
names both correspond to real-world entities.)
DNS server was hardcoded to 8.8.8.8. That is an actual DNS server provided
by Google. Its use may be somewhat suboptimal, but that was one parameter
that should work "out-of-box". Reverted it to 192.0.2.1. Changed other
parameters to 192.0.2.0/24.
> Note: as part of any refactoring, we may want to typedef the
boost::shared_ptr templates for Option and Pkt4/6.
Agree.
> processDiscover()/processRequest(): is there a need for a blank line
between the call to copyDefaultField() and appendDefaultOptions()? Both
are concerned with initializing the response packet. (Also, perhaps these
steps deserve a comment?).
No. Removed and added appendRequestedOptions(). This method is a simple
for now, but it will be greatly expanded in the future. It not just
assumes that client requested DNS addresses and domain name.
> processDiscover() and processRequest() appear to be identical. Granted
there is packet-specific code that is not implemented yet, but the common
functionality should be abstracted into a single method.
They are for now, with the exception of a different message type. They
will be different soon, though. As both are 5 lines long, I plan to keep
them separated. It does not make much sense to unify them, just to have
them split in two months.
> copyDefaultFields(): Can set the size of a vector at initialization time
with
> {{{
> vector<uint8_t> mac(Pkt4::MAX_CHADDR_LEN);
> }}}
> Even better though, as the next operation is to copy the chaddr field
from "question" is to initialize it from the question, i.e.
> {{{
> vector<uint8_t> mac(question->getChaddr(),
> question->getChaddr() + Pkt4::MAX_CHADDR_LEN);
> }}}
Done.
> copyDefaultFields()/appendDefaultOptions(): They are OK here for the
moment. But I can't help thinking that these logically belong to a
"Response4" class, derived from Pkt4, that encapsulates a response. The
reason being that these are essentially initialization operations of the
response and are not dependent on the state of the server. Alternatively,
if they are part of the Pkt4 class, operations can take place without
involving the accessor methods. This would have implications in
copyDefaultFields, where an intermediate vector is created to convey the
MAC address from the question to the answer: if the operation were part of
the Pkt4 class, the vector would not be needed.
That is a good approach in theory. It is reasonable from object oriented
programming, but it is very inconvenient from practical perspective. I
fell into this trap with dibbler. It would be great if there were a single
place where message is constructed and options are added. It is especially
useful during early stage, when code is not stable and evolves quickly.
"We didn't send option X? Need to find out why" is a very frequent
scenario.
> '''src/bin/dhcp4/tests/dhcp4_srv_unittest.cc'''[[BR]]
> processDiscover and processRequest tests: comment above about
initializing a vector to a specific size applies.
Done.
>
> '''src/lib/dhcp/option.cc'''[[BR]]
> Not part of the change, but I was looking at the getUintX() methods and
think there is a problem. If I store a uint32_t value in an option, then
retrieve it with a uint8_t, I may not get the same value stored:
> * if the value is greater than 255, the answer will be incorrect.
> * if the value is 255 or less, the answer ''may'' be correct, depending
on whether I am running on a little-endian or big-endian machine.
> I suggest that internally the getUintX methods should retrieve the value
using the data type of the appropriate size, then convert it to the
correct type using boost::lexical_cast.
No. That would be wrong. This is really a convenient way to not have
Option_uint8, Option_uint16 and Option_uint32 (or a template that produces
them). If an option stores integer value on 32 bits, you really should
read it as 32 bits.
I agree that this could be misused to read only part of the option (e.g.
option is 32 bits, but someone cares only for first 16 bits, so uses
getUint16). To forbid such behavior, perhaps the best way would be to
change size checks from less than sizeof(uintX) to not equal
sizeof(uintX)?
> '''src/lib/dhcp/pkt4.cc'''[[BR]]
> unpack(): typo in a comment "fist use of readVector".
Fixed.
--
Ticket URL: <http://bind10.isc.org/ticket/1230#comment:5>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list