-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
QuicConnectionListener is configured using an IPEndPoint
. There is some special case logic if the IPAddress
of the endpoint is IPAddress.Any
or IPAddress.IPv6Any
.
Lines 27 to 42 in c59d200
if (endpoint.Address != IPAddress.Any && endpoint.Address != IPAddress.IPv6Any) | |
{ | |
switch (endpoint.Address.AddressFamily) | |
{ | |
case AddressFamily.InterNetwork: | |
endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan<byte>(ref socketAddress.Ipv4.sin_addr[0], 4), out _); | |
socketAddress.Ipv4.sin_family = (ushort)QUIC_ADDRESS_FAMILY.INET; | |
break; | |
case AddressFamily.InterNetworkV6: | |
endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan<byte>(ref socketAddress.Ipv6.sin6_addr[0], 16), out _); | |
socketAddress.Ipv6.sin6_family = (ushort)QUIC_ADDRESS_FAMILY.INET6; | |
break; | |
default: | |
throw new ArgumentException(SR.net_quic_addressfamily_notsupported); | |
} | |
} |
The problem here is the check is using !=
operator which isn't overloaded. That means it is checking by reference. It is possible for someone to create a copy of one of these static known IPAddress
instances (and have the same internal byte value) causing them to no longer pass this check.
The solution is to change from operators to using Equal
, which IPAddress
overrides:
Before:
if (endpoint.Address != IPAddress.Any && endpoint.Address != IPAddress.IPv6Any)
After:
if (!endpoint.Address.Equals(IPAddress.Any) && !endpoint.Address.Equals(IPAddress.IPv6Any))
We ran into this problem in Kestrel. We have a temporary workaround: dotnet/aspnetcore#35258