-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dhcpv4: simplify option parsing. #224
Conversation
This will have very minor merge conflicts with #223. I'll resolve depending on whichever gets approved & submitted first. |
1cf1137
to
ef2cb2d
Compare
Codecov Report
@@ Coverage Diff @@
## master #224 +/- ##
==========================================
- Coverage 73.96% 72.95% -1.02%
==========================================
Files 84 84
Lines 4118 3797 -321
==========================================
- Hits 3046 2770 -276
+ Misses 935 912 -23
+ Partials 137 115 -22
Continue to review full report at Codecov.
|
ef2cb2d
to
6d742d2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of nits/questions, nothing blocking.
) | ||
|
||
// OptDefaultBootImageID contains the selected boot image ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved back down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not how Go comments work?
The diff may make it weird to read, but this is
// OptDefaultBootImageID contains the selected boot image ID.
//
// Implements the BSDP option default boot image ID, which tells the client
// which image is the default boot image if one is not selected.
type OptDefaultBootImageID ...
@@ -11,20 +9,17 @@ import ( | |||
// OptVendorSpecificInformation encapsulates the BSDP-specific options used for | |||
// the protocol. | |||
type OptVendorSpecificInformation struct { | |||
Options []dhcpv4.Option | |||
Options dhcpv4.Options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure that I like this particular type alias - what's wrong with just having it as a slice? it's more clear that it's a slice of a struct/interface, rather than having to look at what a dhcpv4.Options
is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also asked this in the original PR, and IIRC @hugelgupf replied (not here, offline) that a rework that doesn't require this new type was ongoing. @hugelgupf is this still the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here's the deal. You've got the []dhcpv4.Option type in a couple of places: DHCPv4, OptRelayAgentInfo, and here.
A dhcpv4.Options type can be the one place to implement the following:
func (Options) Get(...)
func (Options) Has(...)
func (Options) Add(...)
func (Options) Update(...)
rather than reimplementing GetOption and GetOneOption on multiple types and having the OptionGetter interface, just implement it on Options and spread Options around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I.e. there is no need to have both
func (o *OptVendorSpecificInformation) GetOption(code dhcpv4.OptionCode) []dhcpv4.Option { |
Line 366 in 108ed92
func (d *DHCPv4) GetOption(code OptionCode) []Option { |
and eventually you'll start replicating HasOption and UpdateOption and AddOption to OptVendorSpecificInformation as well as the relay agent stuff... so an Options type saves you that work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I get how this works, and in an isolated context it makes perfectly sense from a compactness perspective. I think it introduces a bit more confusion, but it's probably acceptable compared to the benefits of a better / more compact interface. As long as we use always Options
instead of []Option
I guess this is OK. If we don't like it at any stage it's always possible to go back. Let's go with Options
now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This PR greatly increases the readability and reduces the complexity. Just a few things to be clarified and potentially changed, as per the inline comments
@@ -11,20 +9,17 @@ import ( | |||
// OptVendorSpecificInformation encapsulates the BSDP-specific options used for | |||
// the protocol. | |||
type OptVendorSpecificInformation struct { | |||
Options []dhcpv4.Option | |||
Options dhcpv4.Options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also asked this in the original PR, and IIRC @hugelgupf replied (not here, offline) that a rework that doesn't require this new type was ongoing. @hugelgupf is this still the case?
// describing what they are. | ||
var OptionCodeToString = map[dhcpv4.OptionCode]string{ | ||
var optionCodeToString = map[dhcpv4.OptionCode]string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with this becoming private, how does a user convert an option code to its name if they want to? Only OptionGeneric
seems to allow a form of access to this map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OptionCode.String()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Argh, yeah, for bsdp this is kinda weird. There's a commit way down the line to make the printing right, but for now, this is a weird thing to expose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose I should try to fix this in this PR. Let me see what I can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, in this PR it doesn't matter yet -- each Option in BSDP prints its own option name statically anyway: https://github.com/insomniacslk/dhcp/pull/224/files#diff-d173dc6740eaa1ad94d4f356b77a647eR32
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hate BSDP -.-
option's codes and lengths were being parsed twice: once in ParseOption and once in each option type's Parse implementation. Consolidate such that it only happens once. Additionally, only pass data to options that they should parse -- we know the length before the Parse function is called, so the option only gets to see the data it needs to see. Also, use uio.Lexer to simplify parsing code in general. Easier to read and reason about.
6d742d2
to
3d2d1c7
Compare
3d2d1c7
to
e7673a0
Compare
Thanks! This fixes #22. It looks good to me. |
e7673a0
to
2ba543b
Compare
@pmazzini sry, force pushed to clean something up, mind approving again? |
Thanks a lot for this PR @hugelgupf ! |
option's codes and lengths were being parsed twice: once in ParseOption
and once in each option type's Parse implementation. Consolidate such
that it only happens once.
Additionally, only pass data to options that they should parse -- we
know the length before the Parse function is called, so the option only
gets to see the data it needs to see.
Also, use uio.Lexer to simplify parsing code in general. Easier to read
and reason about.