inetaf / netaddr

Network address types

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

what should (1.2.3.4/33).Contains(1.2.3.4) return?

josharian opened this issue · comments

It is easy to manually construct an invalid IPPrefix with too many bits. When used, e.g. with Contains, should it...panic? undefined behavior?

Looking at the case in the title, it's hard to argue for either true or false as the correct answer. UB is generally a bummer. So I'm leaning towards panic.

Opinions wanted.

@bradfitz @danderson @mdlayher

My intuition is that (1.2.3.4/33).Contains(1.2.3.4) is false.

I'm not sure why, but unpacking a bit, I think I consider this equivalent to (fe80::/64).Contains(1.2.3.4). The two operands are different "kinds", and so cannot contain each other. I suppose the logical leap I'm making is that 1.2.3.4/33 is obviously not an IPv4 prefix, and therefore the same logic as v6-vs-v4 applies.

I'm reluctant to introduce panics in low-level code, especially where the input might be attacker controlled. That said, arguing against myself: ParseIPPrefix will reject invalid lengths, so the remaining risk is the programmer manually constructing a wrong IPPrefix. Maybe that's sufficiently "you went out of your way to get it wrong" to be okay for a panic?

If we do panic, let's definitely add IPPrefix.Valid to give programmers an easy way to verify a prefix before they call something panicky.

therefore the same logic as v6-vs-v4 applies.

What about (::1/129).Contains(::1), then? One argument for true is: They don't differ in any of the first 129 bits. One argument for false is: It's not possible for ::1 to match the first 129 bits of ::1/129, because it doesn't have 129 bits. It's really a nonsensical question. I think we need either UB or panic.

Same logic, imo: ::1/129 is obviously not an IPv6 prefix, since IPv6 prefixes can't be 129 bits long. Therefore, ::1, which is an IPv6 address, cannot be contained by this not-IPv6 prefix.

I think if we add IPPrefix.Valid, and specify that Contains returns false for invalid prefixes, it'll give us defined and (I would argue) reasonable behavior, without a panic.

Yeah, I'd vote not panicking, returning false, and adding Valid.

Reviewed other methods and inserted uses of Valid where appropriate.