Skip to content

Conversation

@jvff
Copy link

@jvff jvff commented Feb 15, 2020

This PR implements the Sub trait for IpNetwork, Ipv4Network and Ipv6Network. There are two possibilities: either a single IP network item is subtracted from the original IP network, or multiple IP network items are subtracted from the original IP network.

The result of the subtraction operation is always an iterator, which can contain zero or more IP network items. For subtracting a single item, the iterator has a rather simple representation in memory and does implement Copy. When subtracting multiple items, a linked list of Box<dyn Iterator> is returned, so the resulting type has a more complex representation.

With this PR it is still not currently possible to subtract between IP networks with different protocols (for example, subtract an IPv4 network from an IPv6 network or vice-versa). Attempting to do so will lead the code to panic.

jvff added 12 commits February 14, 2020 00:28
This is a helper type that is created with an initial IPv4 network,
represented as a `u32` representation of its IP address and a `u8` with
its prefix, and the prefix of a larger IPv4 network which contains the
initial IPv4 network. Since one is contained in the other, the IP
address shares most bits, so it only needs to keep track of it once.
However, proper care must be taken so that the initial network prefix is
larger than the larger network prefix.

The iterator will produce `Ipv4Network` items representing increasing
network ranges that are still inside the larger network but do not
include the initial network.
This is also an iterator, and it wraps around the `Ipv4NetworkSubSet`
type. However, it also includes entries for when the minuend and the
subtrahend don't overlap and for when the subtrahend completly ovelaps
the minuend.

In the former case, there is no overlap of the networks. Therefore,
nothing is subtracted from the original network (the minuend), so the
result is just the original network.

In the latter case, since the subtrahend completly overlaps the minuend,
it is in effect completely removing the original network. Therefore, the
result is no networks at all, and the resulting iterator is empty.
The resulting set is returned through a `Ipv4NetworkSubResult` helper
iterator.
This allows one to subtract multiple `Ipv4Network`s from a single
`Ipv4Network`. This works by having a subtraction chain, where the
original minuend `Ipv4Network` is subtracted by the first `Ipv4Network`
subtrahend, and the result is then subtracted by the second
`Ipv4Network` subtrahend, and so on.

The implementation uses dynamic dispatch because it is impossible to
know how many subtrahends there will be. This is a simple initial
implementation, and tere might be other solutions, such as creating a
custom iterator and looping around all subtrahends to provide the
results, but it quickly becomes more complicated. This might be doable
as future work.

Another possible future work is to remove the dynamic dispatch for known
sizes of subtrahend arrays, but this would probably require const
generics to be stabilized.
This is the IPv6 equivalent of the `Ipv4NetworkSubSet`.

It is a helper type that is created with an initial IPv6 network,
represented as a `u128` representation of its IP address and a `u8` with
its prefix, and the prefix of a larger IPv6 network which contains the
initial IPv6 network. Since one is contained in the other, the IP
address shares most bits, so it only needs to keep track of it once.
However, proper care must be taken so that the initial network prefix is
larger than the larger network prefix.

The iterator will produce `Ipv6Network` items representing increasing
network ranges that are still inside the larger network but do not
include the initial network.
This is the IPv6 equivalent to the `Ipv4NetworkSubResult` type.

This is also an iterator, and it wraps around the `Ipv6NetworkSubSet`
type. However, it also includes entries for when the minuend and the
subtrahend don't overlap and for when the subtrahend completly ovelaps
the minuend.

In the former case, there is no overlap of the networks. Therefore,
nothing is subtracted from the original network (the minuend), so the
result is just the original network.

In the latter case, since the subtrahend completly overlaps the minuend,
it is in effect completely removing the original network. Therefore, the
result is no networks at all, and the resulting iterator is empty.
The resulting set is returned through a `Ipv6NetworkSubResult` helper
iterator.
This allows one to subtract multiple `Ipv6Network`s from a single
`Ipv6Network`. This works by having a subtraction chain, where the
original minuend `Ipv6Network` is subtracted by the first `Ipv6Network`
subtrahend, and the result is then subtracted by the second
`Ipv6Network` subtrahend, and so on.

The implementation uses dynamic dispatch because it is impossible to
know how many subtrahends there will be. This is a simple initial
implementation, and tere might be other solutions, such as creating a
custom iterator and looping around all subtrahends to provide the
results, but it quickly becomes more complicated. This might be doable
as future work.

Another possible future work is to remove the dynamic dispatch for known
sizes of subtrahend arrays, but this would probably require const
generics to be stabilized.
This type represents the result of the subtraction of one `IpNetwork`
from another. The implementation just wraps the resulting subtraction of
the protocol specific (IPv4 or IPv6) subtraction result.

Note that this means that it is not currently possible to subtract
`IpNetwork`s of different protocols (i.e., either an IPv4 network from
an IPv6 network or vice-versa).
The resulting set is returned through a `IpNetworkSubResult` helper
iterator.

Note that it is not currently possible to subtract `IpNetwork`s of
different protocols (i.e., either an IPv4 network from an IPv6 network
or vice-versa).
This allows one to subtract multiple `IpNetwork`s from a single
`IpNetwork`. This works by having a subtraction chain, where the
original minuend `IpNetwork` is subtracted by the first `IpNetwork`
subtrahend, and the result is then subtracted by the second
`IpNetwork` subtrahend, and so on.

Since it isn't currently possible to subtract `IpNetworks` of different
protocols, all operands must be of the same protocol (either IPv4 or
IPv6). Having one operand of a different protocol will cause the code to
panic.

The implementation uses dynamic dispatch because it is impossible to
know how many subtrahends there will be. This is a simple initial
implementation, and tere might be other solutions, such as creating a
custom iterator and looping around all subtrahends to provide the
results, but it quickly becomes more complicated. This might be doable
as future work.

Another possible future work is to remove the dynamic dispatch for known
sizes of subtrahend arrays, but this would probably require const
generics to be stabilized.
@ctrlcctrlv
Copy link
Contributor

this pr is cool

@Alextopher Alextopher mentioned this pull request Apr 29, 2024
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.

2 participants