-
Notifications
You must be signed in to change notification settings - Fork 3
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
fix: correctly compare compressed/expanded ipv6 in targets #109
Conversation
6681a64
to
efb9dd5
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #109 +/- ##
==========================================
+ Coverage 41.23% 41.42% +0.19%
==========================================
Files 75 75
Lines 10793 10840 +47
==========================================
+ Hits 4450 4491 +41
- Misses 5881 5885 +4
- Partials 462 464 +2 ☔ View full report in Codecov by Sentry. |
parts := strings.Split(hostname, ":") | ||
return len(parts) > 2 |
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 can be prone to errors or to be misused. Why not use https://pkg.go.dev/net/netip#ParseAddr and https://pkg.go.dev/net/netip#Addr.Is6 ?
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.
As silly as it may look, this is enough to catch all combinations of targets in IPv6 format, including the one with port and brackets like [2600:1f16:1784:fa03:fd73::e]:1326
, which the library wouldn't consider as v6
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.
Wouldn't https://pkg.go.dev/net/netip#ParseAddrPort work for this then?
I'm just worried that this func is very easy to abuse.
isIPv6("this:is:nuts:!")
will also return true
. It will also return true for 1:2:3:4
which http://sqa.fyicenter.com/1000334_IPv6_Address_Validator.html#Result reports as invalid.
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.
ParseAddrPort
works if the port is always there, but it would fail to parse things like ::1
(would work with [::1]:8000
though).
If you really feel strong about this we can improve this validation, but generally decK (or this library) doesn't do much input validation other than what's part of the JSON schemas from go-kong.
For the records though, those bogus entries would still fail validation at a later stage:
$ ./deck gateway sync kong.yaml
Error: building state: invalid ipv6 address 1:2:3:4
$ ./deck gateway sync kong.yaml
Error: building state: invalid ipv6 address this:is:nuts:!
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.
Understood that this is validated on other levels.
I'm just suggesting to consider improving the reliability of this while we're at it
For instance something like this should work just fine and will work for addresses with and without ports
func IsIPv6(str string) bool {
addr, err := netip.ParseAddrPort(str)
if err != nil {
addr, err := netip.ParseAddr(str)
fmt.Printf("error parsing address: %v\n", err)
if err != nil {
fmt.Printf("error parsing address port: %v\n", err)
return false
}
return addr.Is6()
}
return addr.Addr().Is6()
}
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 still would fail to parse something like [::1]
, as well as detecting bogus patterns like [invalid:ipv6::address]:1326
: the function would rightly return false
, but this is not just false
, it's invalid. At this point we would need add extra handling and validation for these cases too. I think this is going to become more complex and fragile overall.
I'm renaming this function to hasIPv6Format
which better represent its purpose: 6764fd2
When syncing a target with a compressed IPv6 (for example `[2001:db8:fd73::e]:1326`) decK can successfully create it but it fails to detect its existence when pulling the config from the API because the CP expands the address (for example to `[2001:0db8:fd73:0000:0000:0000:0000:000e]:1326`) causing decK to attempt to recreate the target and failing because the target already exists. This commit fixes this by using some helpers to expand the ipv6 before trying to sync/dump.
efb9dd5
to
88f11dc
Compare
// normalizeIPv6 normalizes an ipv6 address to the format [address]:port. | ||
// for example: | ||
// from ::1 to [0000:0000:0000:0000:0000:0000:0000:0001]:8000. | ||
func normalizeIPv6(target string) (string, error) { |
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.
Couldn't we also use StringExpanded()
here? Possibly with a port?
parts := strings.Split(hostname, ":") | ||
return len(parts) > 2 |
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.
Wouldn't https://pkg.go.dev/net/netip#ParseAddrPort work for this then?
I'm just worried that this func is very easy to abuse.
isIPv6("this:is:nuts:!")
will also return true
. It will also return true for 1:2:3:4
which http://sqa.fyicenter.com/1000334_IPv6_Address_Validator.html#Result reports as invalid.
89b734e
to
1bcb5a5
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.
Code looks good and serves it's purpose 👍
Feel free to address the comments or merge as is if time is of the essence.
When syncing a target with a compressed IPv6 (for example
[2001:db8:fd73::e]:1326
) decK can successfully create it but it fails to detect its existence when pulling the config from the API because the CP expands the address (for example to[2001:0db8:fd73:0000:0000:0000:0000:000e]:1326
) causing decK to attempt to recreate the target and failing because the target already exists.This commit fixes this by using some helpers to expand the ipv6 before trying to sync/dump.
Summary
SUMMARY_GOES_HERE
Full changelog
Issues resolved
Fix #XXX
Documentation
Testing