-
Notifications
You must be signed in to change notification settings - Fork 19
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
ACP: Extended logic for IP networks #235
Comments
Seconded. I am skeptical of the "implement bit arithmetic traits" path here though, and would like to see alternatives such as "semantically meaningful named methods" instead. |
imho we'd probably also want a create-mask-from-bit-count method |
Agreed, and I'd add some overflow checking as well
|
I should add, part of the the thought process for implementing bit operations directly instead of putting them under named methods is that:
That said, the "create mask from bit count" would be a good operation to include here since it doesn't have as direct of a connection to any existing operation, since it involves bit-shifting. I personally would not think that implementing bit-shift operations for IPs is meaningful, but a method that converts a prefix length to a mask would be good in addition to something like Also, while it is awkward to use, implementing |
I don't think we are supposed to be debating the API so much here right? That's why I seconded it. I added my other comment to clarify that I was not fully on board with the API as proposed, but that idea and problem space may be worth addressing some way. I think the next step is to file a tracking issue and then we can start digging into the API design arguments. :) (My understanding of the ACP process could be wrong.) |
As I understand it, the ACP process is for both nailing down the problem & the solution, although only the problem has to be included in the initial proposal, since the solution is part of the discussion. I could also be wrong, though. |
It might be worth adding cidr to the “Links and related work” section. |
We briefly discussed this in a libs-api meeting. We thought the No objections to BitAnd, BitOr, Not, Step and BITS. (Note that the trait implementations can unfortunately not be added as unstable, so those will directly need an FCP.) |
Although I linked this there, figure I might as well make a comment including the PRs I created now that the ACP is merged:
|
Is the BitAnd meaningful when the second address is not a mask? Same also for other traits like "Not". What exactly does it mean to "Not" an ordinary IP address? Shouldn't we implement a type "Mask" and only allow operations on those? |
I mean, what does it mean to "not" an integer that just represents the count of something? These types have multiple meanings and it's not super worth it to separate them out for these purposes since it just makes the type logic weird. For example, we'd want to have a |
I wouldn't want a |
Add BITS, from_bits, to_bits to IP addresses ACP: rust-lang/libs-team#235 Tracking issue: rust-lang#113744
Add BITS, from_bits, to_bits to IP addresses ACP: rust-lang/libs-team#235 Tracking issue: #113744
impl Step for IP addresses ACP: rust-lang/libs-team#235 Note: since this is insta-stable, it requires an FCP. Separating out from the bit operations PR since it feels logically disjoint, and so their FCPs can be separate.
impl Step for IP addresses ACP: rust-lang/libs-team#235 Note: since this is insta-stable, it requires an FCP. Separating out from the bit operations PR since it feels logically disjoint, and so their FCPs can be separate.
impl Not, Bit{And,Or}{,Assign} for IP addresses ACP: rust-lang/libs-team#235 Note: since these are insta-stable, these require an FCP. Implements, where `N` is either `4` or `6`: ```rust impl Not for IpvNAddr impl Not for &IpvNAddr impl BitAnd<IpvNAddr> for IpvNAddr impl BitAnd<&IpvNAddr> for IpvNAddr impl BitAnd<IpvNAddr> for &IpvNAddr impl BitAnd<&IpvNAddr> for &IpvNAddr impl BitAndAssign<IpvNAddr> for IpvNAddr impl BitAndAssign<&IpvNAddr> for IpvNAddr impl BitOr<IpvNAddr> for IpvNAddr impl BitOr<&IpvNAddr> for IpvNAddr impl BitOr<IpvNAddr> for &IpvNAddr impl BitOr<&IpvNAddr> for &IpvNAddr impl BitOrAssign<IpvNAddr> for IpvNAddr impl BitOrAssign<&IpvNAddr> for IpvNAddr ```
impl Not, Bit{And,Or}{,Assign} for IP addresses ACP: rust-lang/libs-team#235 Note: since these are insta-stable, these require an FCP. Implements, where `N` is either `4` or `6`: ```rust impl Not for IpvNAddr impl Not for &IpvNAddr impl BitAnd<IpvNAddr> for IpvNAddr impl BitAnd<&IpvNAddr> for IpvNAddr impl BitAnd<IpvNAddr> for &IpvNAddr impl BitAnd<&IpvNAddr> for &IpvNAddr impl BitAndAssign<IpvNAddr> for IpvNAddr impl BitAndAssign<&IpvNAddr> for IpvNAddr impl BitOr<IpvNAddr> for IpvNAddr impl BitOr<&IpvNAddr> for IpvNAddr impl BitOr<IpvNAddr> for &IpvNAddr impl BitOr<&IpvNAddr> for &IpvNAddr impl BitOrAssign<IpvNAddr> for IpvNAddr impl BitOrAssign<&IpvNAddr> for IpvNAddr ```
Add BITS, from_bits, to_bits to IP addresses ACP: rust-lang/libs-team#235 Tracking issue: #113744
Add BITS, from_bits, to_bits to IP addresses ACP: rust-lang/libs-team#235 Tracking issue: #113744
Add BITS, from_bits, to_bits to IP addresses ACP: rust-lang/libs-team#235 Tracking issue: #113744
Proposal
Problem statement
While most networked applications only need to deal with individual IP addresses, it is sometimes desirable to work with entire ranges of IP addresses, especially under IPv6.
Motivating examples or use cases
The primary use case for most workflows will be filtering (allow-listing or deny-listing) ranges of IPs for connections, although more dedicated networking code that routes traffic among several hosts could also benefit from this.
Additionally, configuring IP addresses for certain applications can benefit from logic surrounding IP networks. For example, under IPv6, it's very common for a host to have access to an entire 64-bit address space and to have free reign over which specific addresses they actually listen on. In these cases, ad-hoc connections can be made on a randomized IP address within this space, where a randomly chosen IP is then checked for collision with an existing address rather than iterating over all possible addresses.
Solution sketch
A good minimal proposal is the following:
BitAnd
andBitOr
impls forIpv4Addr
andIpv6Addr
(not forIpAddr
, since the operands must be the same address type)Not
forIpv4Addr
,Ipv6Addr
, and maybeIpAddr
(we can implement this for generic IP addresses, but I'm not sure if it'd be useful)leading_zeros
,leading_ones
,trailing_zeros
, andtrailing_ones
methods forIpv4Addr
,Ipv6Addr
, and potentiallyIpAddr
(there isn't the same restriction as for binary operations, although it's likely you'll still need to narrow down the address type anyway)BITS
associated constant forIpv4Addr
andIpv6Addr
set to 32 and 128 respectivelyStep
forIpv4Addr
andIpv6Addr
(again not forIpAddr
, since ranges of IPs must have the same type on both ends)Note that this proposal does not currently include separate IP network types, although that could be a future extension. The main benefit here is to provide operations which can only be provided by the standard library since it owns the IP address types, while leaving the usage of those operations to implement dedicated types up to the end user and various crate authors.
Examples
Checking a network mask with
BitAnd
:Creating an address in a network with
BitOr
:Checking validity of a network mask:
Getting the first and last IPs in a network:
Alternatives
All of these operations could be done through the conversions to
u32
andu128
, and this is indeed what existing crates do. The primary alternative would be to have users rely on these conversions for any of the proposed operations that are not implemented.Links and related work
Some existing IP network crates:
ipnet
ipnetwork
ip-network
cidr
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution:
The text was updated successfully, but these errors were encountered: