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

proposal: support for net/netip types #88

Open
ainar-g opened this issue Jun 29, 2022 · 7 comments
Open

proposal: support for net/netip types #88

ainar-g opened this issue Jun 29, 2022 · 7 comments

Comments

@ainar-g
Copy link

ainar-g commented Jun 29, 2022

Go 1.18 includes the new net/netip package with value types related to IP addresses and networks.

Perhaps, new methods should be added, for example Reader.LookupAddr(ip netip.Addr, result any) and Reader.Prefixes with a corresponding iterator, that would encourage the use of the new IP types. I think, it could also reduce some of the boilerplate such as:

maxminddb-golang/reader.go

Lines 247 to 250 in ccd731c

ipV4Address := ip.To4()
if ipV4Address != nil {
ip = ipV4Address
}

and a lot of len(ip) == net.IPv4len and ip.To4() == nil.

@oschwald
Copy link
Owner

I'd also like to see this. That said, I am planning on waiting until 1.19 is released and 1.17 has been end-of-lifed.

@costela
Copy link

costela commented Sep 1, 2022

Now that 1.19 is out and 1.17 is EOL, can we reconsider this? 🙏

@oschwald
Copy link
Owner

oschwald commented Sep 2, 2022

Is there a particular use case beyond avoiding an AsSlice() call in your code? Internally, we will still need to convert the address to a byte slice, meaning that a net/netip version will likely cause an extra allocation over the current lookup methods. The number of lookup methods is also somewhat unwieldy already and I am not sure I want to add a net/netip variant of each.

@costela
Copy link

costela commented Sep 2, 2022

Is there a particular use case beyond avoiding an AsSlice() call in your code?

Not really. I just had a cursory look at the code and naively expected the migration to be useful in a few cases. But nothing concrete.

The number of lookup methods is also somewhat unwieldy already and I am not sure I want to add a net/netip variant of each.

Totally understandable 👍

@ainar-g
Copy link
Author

ainar-g commented Sep 20, 2022

@oschwald, sorry for the long delay.

Is there a particular use case beyond avoiding an AsSlice() call in your code?

Not just AsSlice, but FromSlice as well. As well as additional calls for netip.Prefix handling.

And it's not actually as easy, see golang/go#53607 and the related issues. In short, net.IP doesn't distinguish between IPv4 and IPv6-mapped-IPv4 addresses, while netip.Addr does, so a naïve conversion will result in a netip.Addr for which Is6 returns true despite the fact that it's an IPv4 address. Since the package already has the information about the correct protocol, it returning the correct addresses and subnets would be greatly appreciated.

Internally, we will still need to convert the address to a byte slice, meaning that a net/netip version will likely cause an extra allocation over the current lookup methods.

It's hard to judge the real impact here without benchmarks, but since netip.Addr is essentially a value type, the number of allocations shouldn't become that much higher. In particular, I feel like if netip.Addr is made the primary internal type, and the conversion is only done when accepting and returning net.IP and friends, the number of allocations should stay approximately the same.

@oschwald
Copy link
Owner

netip.Addr does not make sense as the primary internal type. As mentioned, we would need to immediately convert it to a slice so that we can access the individual bits. Whether that slice is a net.IP or a []byte is somewhat immaterial. As such, the netip.Addr path would require an extra allocation over the net.IP path as a conversion to a slice would be necessary.

Also, net.IP not distinguishing between IPv4 and IPv4-mapped IPv6 addresses, that is actually an advantage in this case as the MMDB format is similar.

As far as *net.IPNet requiring extra work, that is a fair point. However, I believe those methods are less frequently used.

@database64128
Copy link

netip.Addr does not make sense as the primary internal type. As mentioned, we would need to immediately convert it to a slice so that we can access the individual bits.

Maybe we can use As4() and As16() and create a slice from the returned array, if the compiler is smart enough to figure out that the slice won't have to be heap allocated. Or just use [16]byte as the primary internal type.

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

No branches or pull requests

4 participants