Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two equal IPv6 IPAddress instances return different GetHashCode results

I have two clients that create IPAddress instances from the same byte[] and send it to the server over WCF (using DataContractSerializer).

On the server, these IPAddress instances are inserted as keys in a dictionary but for some reason they're added as different keys.

When logging I see that they're equal but GetHashCode returns different results.

var client1Address = // sent from client1
var client2Address = // sent from client2

Console.WriteLine(client1Address.Equals(client2Address));
Console.WriteLine(client1Address.GetHashCode().Equals(client2Address.GetHashCode()));

Output:

true
false

How can equal IPAddress instances return different GetHashCode results?

like image 945
Sivan Krigsman Avatar asked Feb 11 '15 17:02

Sivan Krigsman


1 Answers

The GetHashCode implementation of IPAddress for IPv6 is:

if (m_HashCode == 0)
{
    m_HashCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode(ToString()); 
    return m_HashCode;
}

To avoid recalculating the hash code again and again, they’re storing the result in a private member. This private member is then serialized to the remote server.

The thing is, that StringComparer.InvariantCultureIgnoreCase.GetHashCode(ToString()) returns different results on different OS versions, and since m_HashCode is serialized as well, the server does not recalculate it.

This results in two identical IPAddress instances with different GetHashCode results.

I think that the private member m_HashCode should be marked as [NonSerialized], that will cause GetHashCode to re-generate the hash code locally and correctly.

As a workaround, I interfered in the serialization process and serialized as a byte[].


Here's the bug on VisualStudio connect. This link is dead as the bug was closed for these reasons:

"Thank you for reporting this issue. Unfortunately, our team is not able to address this issue due to other, higher priority items. Further, any changes to the serialized content of a type result in a risk of breaking apps that have taken a dependency on that behavior. "

like image 51
Sivan Krigsman Avatar answered Oct 05 '22 05:10

Sivan Krigsman