-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Updated ipHash to calculate over the actual IP #855
Conversation
I can't reproduce this, for me it looks like in both cases I see the 16 byte version. Given the shorter form is coming from DNS it could be many differences in the path through the DNS libraries you end up taking (I tried with Go 1.17.3 on darwin/arm64 and Go 1.16.5 on linux/amd64).
Not always, see the description of the IP type at https://pkg.go.dev/net#IP -- it's either a 4 byte or 16 byte slice, if it's 16 byte it's in the IPv4 mapped form (with I think you're along the right lines though, this is varying when it's a 4-byte vs 16-byte slice, but like I said I can't reproduce seeing the 4 byte slice. Entirely changing the hash seems a bit drastic though. I think a better approach would be to always hash the 16 byte address, i.e. [I'm not a maintainer of this, but if you're willing to update your PR to use To16() I think that would be reasonable, please also follow the DCO process to add the |
Signed-off-by: Magnus Appelquist <[email protected]>
e44c092
to
a9d5f39
Compare
My first thought was to use To16(), but the hash differ. This is because the IP can be either one of these two string: 8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0. Agree, that it could be caused by dns libraries. However, you should be able to reproduce it using the linux compiled binary. Have you ipv6 enabled in your setup? Please also test with both "preferred_ip_ protocol ip4", "preferred_ip_ protocol ip6" (and with IP or hostname). |
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 agree with @dgl, we don't want to String()
this.
@@ -135,6 +135,6 @@ func chooseProtocol(ctx context.Context, IPProtocol string, fallbackIPProtocol b | |||
|
|||
func ipHash(ip net.IP) float64 { | |||
h := fnv.New32a() | |||
h.Write(ip) | |||
h.Write([]byte(ip.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.
I did some testing, I can reproduce this issue. The fix is this:
h.Write([]byte(ip.String())) | |
if ip.To4() != nil { | |
h.Write(ip.To4()) | |
} else { | |
h.Write(ip.To16()) | |
} |
Q: can we close this in favor of #863? |
Closing in favor of #863. Thanks for finding the bug. |
The ipHash() function generates a hash from the resolved IP.
Because net.IP is a 16 bytes array, sometimes the array have leading 0 (depending if the target is an IP or hostname). Also, an IPv4 address could be represented as 0.0.0.0.0.0.0.0.0.0.255.255.8.8.8.8 in the byte array or just 8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0. This makes the hash unreliable.
Example:
Simply using String() and calculate checksum over the actual IP-string instead will fix this. Also, as a side effect, it is easier to precalculate hash and compare it (for example, I calculate the hash in Python that create metrics that is later compared to see if address resolves correct or not).