Skip to content

[HTTP/3] QuicConnectionListener and IPAddress.Any or IPv6Any #57241

@JamesNK

Description

@JamesNK

QuicConnectionListener is configured using an IPEndPoint. There is some special case logic if the IPAddress of the endpoint is IPAddress.Any or IPAddress.IPv6Any.

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:

image

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions