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

The 'IPNetwork.subnet' function can loop through 2 ^ 128 elements #241

Open
sebastien-rosset opened this issue Jan 24, 2022 · 1 comment

Comments

@sebastien-rosset
Copy link

sebastien-rosset commented Jan 24, 2022

The subnet() function may loop through 2 ^ N elements, where N <= 128.
The subnet function may be invoked for a IPv6 network such as 2600:1f1c:1b3:8f00::/56, count = None and prefix length /120. It calculates the max number of subnets:

width = self._module.width
max_subnets = 2 ** (width - self.prefixlen) // 2 ** (width - prefixlen)

If the network address is /0 and the prefix length is 128, then max_subnets = 2 ^ 128 // 2 ^ 0, which is 2 ^ 128. If the count argument is set to 0, this will cause unbounded CPU usage and memory allocation, netaddr.subnet never returns.

@jstasiak
Copy link
Contributor

Hey @sebastien-rosset, thank you for the report. It seems to be me that this is behaving as expected – the generator yields the subnets that are actually requested.

If the count argument is set to 0, this will cause unbounded CPU usage and memory allocation, netaddr.subnet never returns

I failed to reproduce this. subnet() returns immediately, it returns a generator. The generator then can be iterated (the memory use will remain constant unless the client code stores the results somewhere) or discarded after however many iterations the client code desires. See below:

>>> from netaddr import IPNetwork
>>> net = IPNetwork('2600:1f1c:1b3:8f00::/56')
>>> subnets = net.subnet(128)
>>> 
>>> subnets
<generator object IPNetwork.subnet at 0x101488970>
>>> next(subnets)
IPNetwork('2600:1f1c:1b3:8f00::/128')
>>> next(subnets)
IPNetwork('2600:1f1c:1b3:8f00::1/128')
>>> next(subnets)
IPNetwork('2600:1f1c:1b3:8f00::2/128')
>>> next(subnets)
IPNetwork('2600:1f1c:1b3:8f00::3/128')
>>> next(subnets)

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

2 participants