Sorting for the inet data type randomly returns the wrong result
when you have networks with the same prefix, but different netmasks. This is due to the fact that occassionally there is random (uninitialized?) data in the extra bits past the point where the netmask cares about them. ie (real data from a real live database): 10.0/10 == 00001010.00100000.00100000.00011000 10.0/11 == 00001010.00000000.00000000.00000000 ^ Bad data, normally never seen The v4bitncmp() function was only taking one bit length argument so it would determine that the networks were different, even though they really aren't (and the netmask test wouldn't be used). This ONLY happens if the tuple with the longer bit length is used as the ip_bits() for the v4bitncmp call AND there happens to be junk data in place in the shorter tuple. Odd and random, but I saw it happen a couple times so... Ryan Mooney
This commit is contained in:
parent
5a197810c0
commit
52d39d519a
@ -3,7 +3,7 @@
|
||||
* is for IP V4 CIDR notation, but prepared for V6: just
|
||||
* add the necessary bits where the comments indicate.
|
||||
*
|
||||
* $Id: network.c,v 1.18 2000/02/21 18:49:54 tgl Exp $
|
||||
* $Id: network.c,v 1.19 2000/03/07 23:01:43 momjian Exp $
|
||||
* Jon Postel RIP 16 Oct 1998
|
||||
*/
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
#include "postgres.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
static int v4bitncmp(unsigned int a1, unsigned int a2, int bits);
|
||||
static int v4bitncmp(unsigned int a1, unsigned int a2, int bits1, int bits2);
|
||||
|
||||
/*
|
||||
* Access macros. Add IPV6 support.
|
||||
@ -137,7 +137,7 @@ network_lt(inet *a1, inet *a2)
|
||||
return FALSE;
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
|
||||
int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2));
|
||||
|
||||
return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2))));
|
||||
}
|
||||
@ -166,7 +166,7 @@ network_eq(inet *a1, inet *a2)
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
return ((ip_bits(a1) == ip_bits(a2))
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2)) == 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -192,7 +192,7 @@ network_gt(inet *a1, inet *a2)
|
||||
return FALSE;
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
|
||||
int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2));
|
||||
|
||||
return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2))));
|
||||
}
|
||||
@ -222,7 +222,7 @@ network_sub(inet *a1, inet *a2)
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
return ((ip_bits(a1) > ip_bits(a2))
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2)) == 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -242,7 +242,7 @@ network_subeq(inet *a1, inet *a2)
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
return ((ip_bits(a1) >= ip_bits(a2))
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2)) == 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -262,7 +262,7 @@ network_sup(inet *a1, inet *a2)
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
return ((ip_bits(a1) < ip_bits(a2))
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2)) == 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -282,7 +282,7 @@ network_supeq(inet *a1, inet *a2)
|
||||
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
|
||||
{
|
||||
return ((ip_bits(a1) <= ip_bits(a2))
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
|
||||
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1), ip_bits(a2)) == 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -476,13 +476,16 @@ network_netmask(inet *ip)
|
||||
*/
|
||||
|
||||
static int
|
||||
v4bitncmp(unsigned int a1, unsigned int a2, int bits)
|
||||
v4bitncmp(unsigned int a1, unsigned int a2, int bits1, int bits2)
|
||||
{
|
||||
unsigned long mask = 0;
|
||||
int i;
|
||||
int i, bits;
|
||||
|
||||
bits=(bits1 < bits2) ? bits1 : bits2;
|
||||
|
||||
for (i = 0; i < bits; i++)
|
||||
mask = (mask >> 1) | 0x80000000;
|
||||
|
||||
a1 = ntohl(a1);
|
||||
a2 = ntohl(a2);
|
||||
if ((a1 & mask) < (a2 & mask))
|
||||
|
Loading…
x
Reference in New Issue
Block a user