Re: IpAddress comparison operators lie

From: Amos Jeffries <squid3_at_treenet.co.nz>
Date: Sat, 01 May 2010 19:43:41 +1200

Alex Rousskov wrote:
> On 05/01/2010 12:07 AM, Amos Jeffries wrote:
>> Alex Rousskov wrote:
>>> Current IpAddress comparison operators are broken from logic point
>>> of view. For example, if a and b are IpAddress objects, then
>>>
>>> * both (a < b) and (a > b) are true if exactly one address is NoAddr;
>>>
>> Sorry.
>>
>> (a > b) looks correct.
>>
>> (a < b) should return false on that test instead of true. Or using the
>> AnyAddr test like <= operator does.
>>
>>
>>> * (ip1 == ip2) may be true even if the addresses have different ports
>>>
>>
>> We have to ignore ports in the boolean operators due to all the code
>> which does ACL matching on IPs. The squid.conf provided address has a
>> zero port.
>> If we include port in the comparison we will have to resort to
>> duplicating every address being ACL tested and set its port to zero
>> before doing each the test.
>> It's better to check the addr, then check the addr.GetPort() as needed
>> for the minority of things which check the port.
>
> Hi Amos,
>
> I appreciate ACL needs, but I think it is not acceptable to ignore
> ports in these operators because they should compare IpAddresses and not
> some arbitrary parts of those objects. I see two options:
>
> A) Remove all overloaded comparison operators from IpAddress. Add
> compareWithoutPort() and compareWithPort() methods that return +1/0/-1
> as expected, following all traditional logic rules. This option will
> force folks to think which comparison to use. It will add more work to
> those who want to use C++ operators (e.g., in std::map)
>
> B) Fix all overloaded comparison operators in IpAddress so that they
> apply to the entire object and follow all traditional logic rules. Add
> compareWithoutPort() method. Change ACLs to use compareWithoutPort().
> This option may caught some by surprise because they might think that
> IpAddress does not include port at all and it would take more work to
> replace all current incorrect uses.
>
> Long-term, the right thing to do is to have portless and portfull
> address classes (one using the other) so that the code that does not
> care about ports is not forced to ignore them. It is non-trivial to
> design this right though and the change would be rather big, so let's
> not go there for now.

Post is not the only field of the sockaddr_in6 being ignored by the
"Address" boolean operators. There is family etc.

This object in abstract is primarily a raw address. It's Get*()
operators can retrieve the address-related details which 'happen' to be
passed with it for testing.

The shortest path to conformity is to drop the boolean address operators
and make the code use a.matchIPaddr(b) <> 0 without the convenience of
(a < b) and memcmp() for matching the whole thing.

>
>>> There may be more inconsistencies; I have not checked all possible
>>> combinations.
>>>
>>> These bugs make it impossible to reliably sort or compare addresses
>>> using C++ operators. However, I do not know whether some code already
>>> relies on this broken behavior. Does it? In other words, should we just
>>> fix the operators or is there more to it?
>> None that I know of. +1 to fix IpAddress.
>
> I disagree that ignoring ports in overloaded comparison operators is OK
> so our notions of a fix differ. Will any of the above two options work
> for you?
>

Well I meant make < consistent with <= and add the unit tests.

Amos

-- 
Please be using
   Current Stable Squid 2.7.STABLE9 or 3.1.1
Received on Sat May 01 2010 - 07:43:58 MDT

This archive was generated by hypermail 2.2.0 : Sat May 01 2010 - 12:00:19 MDT