Skip to content
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

Merged
merged 2 commits into from
Jan 10, 2019

Conversation

hugelgupf
Copy link
Collaborator

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.

@hugelgupf
Copy link
Collaborator Author

hugelgupf commented Jan 9, 2019

This will have very minor merge conflicts with #223. I'll resolve depending on whichever gets approved & submitted first.

@codecov
Copy link

codecov bot commented Jan 10, 2019

Codecov Report

Merging #224 into master will decrease coverage by 1.01%.
The diff coverage is 97.28%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
dhcpv4/bsdp/bsdp_option_generic.go 100% <100%> (ø) ⬆️
dhcpv4/option_requested_ip_address.go 100% <100%> (ø) ⬆️
dhcpv4/option_generic.go 100% <100%> (+7.4%) ⬆️
dhcpv4/options.go 94.23% <100%> (+4.48%) ⬆️
dhcpv4/option_maximum_dhcp_message_size.go 100% <100%> (ø) ⬆️
dhcpv4/option_broadcast_address.go 100% <100%> (ø) ⬆️
dhcpv4/option_ip_address_lease_time.go 100% <100%> (ø) ⬆️
dhcpv4/bsdp/bsdp_option_version.go 100% <100%> (ø) ⬆️
dhcpv4/option_message_type.go 100% <100%> (ø) ⬆️
dhcpv4/option_root_path.go 100% <100%> (ø) ⬆️
... and 28 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 108ed92...2ba543b. Read the comment docs.

Copy link
Collaborator

@get9 get9 left a 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.
Copy link
Collaborator

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.

Copy link
Collaborator Author

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 ...

dhcpv4/bsdp/bsdp_option_machine_name.go Show resolved Hide resolved
@@ -11,20 +9,17 @@ import (
// OptVendorSpecificInformation encapsulates the BSDP-specific options used for
// the protocol.
type OptVendorSpecificInformation struct {
Options []dhcpv4.Option
Options dhcpv4.Options
Copy link
Collaborator

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.

Copy link
Owner

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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 {
and
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.

Copy link
Owner

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

dhcpv4/options.go Outdated Show resolved Hide resolved
Copy link
Owner

@insomniacslk insomniacslk left a 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
Copy link
Owner

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{
Copy link
Owner

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OptionCode.String()

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hate BSDP -.-

dhcpv4/dhcpv4.go Show resolved Hide resolved
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.
dhcpv4/dhcpv4.go Outdated Show resolved Hide resolved
@pmazzini
Copy link
Collaborator

Thanks! This fixes #22. It looks good to me.

@hugelgupf
Copy link
Collaborator Author

@pmazzini sry, force pushed to clean something up, mind approving again?

@insomniacslk insomniacslk merged commit 512011c into insomniacslk:master Jan 10, 2019
@insomniacslk
Copy link
Owner

Thanks a lot for this PR @hugelgupf !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants