You can store the network address as a 32 bit integer and the prefix as a 5 bit integer for IPv4 without requiring any string operations. The question I raised is only about whether users should be able to ban arbitrary ranges or only "CIDR ranges".AmigoJack wrote:I discourage storing CIDR notation - that'd be human readable, but comparing IPs would always end up in string operations for the DBMS.
[RFC|Accepted] IP banning to use 'longest prefix matching'
- bantu
- 3.0 Release Manager
- Posts: 557
- Joined: Thu Sep 07, 2006 11:22 am
- Location: Karlsruhe, Germany
- Contact:
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
- AmigoJack
- Registered User
- Posts: 110
- Joined: Wed May 04, 2011 7:47 pm
- Location: グリーン ヒル ゾーン
- Contact:
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
They should be able to do both. At least boards being used in intranets only might have their reasons to ban ranges which can't be expressed in a subnet mask (or would then be forced to use multiple entries). Not to mention that I expect only a fraction of users to know/handle a CIDR notation.
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
I like AmigoJack's proposal.
We just need to separate an IP by its dot decimal having numbers form 0 to 255 for IPv4 and have ":" hexadecimal for IPv6. Using hexadecimal isn't that hard.
For a number like 'ff' we just need to prepend "0x" forming "0xff" and then ask php to parse it as a integer. In order to be platform independent we must work with 32 bit integers and there is no doubt that 0xffff fits in an integer. So we can have an array of integer with all the parts of the IPv6.
Something like:
We could then use something like AmigoJack made to search in the DB and seems like quite straight forward.
I'd also mark the from1, from2, from3, from4, from5, from6, from7, from8 as unique, same for the from. With that both would be indexed and some constraining would be automatically added to prevent duplicates in the from as they are unnecessary.
We just need to separate an IP by its dot decimal having numbers form 0 to 255 for IPv4 and have ":" hexadecimal for IPv6. Using hexadecimal isn't that hard.
For a number like 'ff' we just need to prepend "0x" forming "0xff" and then ask php to parse it as a integer. In order to be platform independent we must work with 32 bit integers and there is no doubt that 0xffff fits in an integer. So we can have an array of integer with all the parts of the IPv6.
Something like:
Code: Select all
$ipv6_parts = explode(':', $ipv6);
foreach($ipv6_parts AS $part => $ip)
{
$ipv6_parts[$part] = (int) '0x' . $ip;
}
I'd also mark the from1, from2, from3, from4, from5, from6, from7, from8 as unique, same for the from. With that both would be indexed and some constraining would be automatically added to prevent duplicates in the from as they are unnecessary.
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
The issue is not so much string operations as the fact that we store a lot more data than we have to. For each banned range (arbitrary range) we should convert endpoints to something that can be compared via less-than. For ipv4 we can use 32-bit integers, for ipv6 we'll have to encode into strings for compatibility most likely. But regardless we'll have one row per banned entry and we could have an index on the lower bound that would be used for querying.
I am not a fan of requiring banned blocks to be /xx subnets.
I am not a fan of requiring banned blocks to be /xx subnets.
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
Not needed. Any database has an integer.Oleg wrote:For ipv4 we can use 32-bit integers, for ipv6 we'll have to encode into strings for compatibility most likely.
E.g. MySQL has the BIGINT that goes form -9223372036854775807 to 9223372036854775807. If it is unsigned it is even bigger.
The problem is with PHP. PHP's int only guarantees from -2147483647 to 2147483647, going out of that is not platform independent. That is not enough to store a complete IPv6 address even though it has space to store each of the 8 fractions of an IPv6 address (each part between the ":").
(Edit: improved english)
- AmigoJack
- Registered User
- Posts: 110
- Joined: Wed May 04, 2011 7:47 pm
- Location: グリーン ヒル ゾーン
- Contact:
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
Why? Where is there any need to use an Integer in PHP? That's the most important advantage of my approach: the database query is always a string and only the database itself uses Integers. No PHP limitations, no beyond-32bit-requirements for the DBMS.brunoais wrote:The problem is with PHP
Of course: if you want to query all IP ranges once and then cache them in PHP code it's another story.
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
ipv6 addresses, being 128 bits long, do not fit into bigints.
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
Yes. That's why I think we should split IPv6 addresses by its parts (by each ":"). Each of those fit into a php's integer.Oleg wrote:ipv6 addresses, being 128 bits long, do not fit into bigints.
We just need to be careful with IP's that usually use "::" like: ::1 or ffff:ff00::gfser:weqe (both are completely valid IPv6 IP's)
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
I am getting the impression that you do not understand the problem being discussed. Please reread the first post and my earlier post here. The issue, again, primarily is with how the banned ips are stored in the database.
Re: [RFC|Accepted] IP banning to use 'longest prefix matchin
^
I still think they should be stored as 8 integers. They are easy to work with and easy to search (if we use indexes, of course). Also, the IPv6 address representaion are already separated into multipart integers (seperated by a ":").
I still think they should be stored as 8 integers. They are easy to work with and easy to search (if we use indexes, of course). Also, the IPv6 address representaion are already separated into multipart integers (seperated by a ":").