Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions aspnetcore/diagnostics/asp0028.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ uid: diagnostics/asp0028

## Cause

On the server machine that supports IPv6, listening to `Any`, rather than `IPv6Any` will either not work or be slower than necessary, because of the [underlying System types implementation](https://github.com/dotnet/runtime/issues/82404).
[IPv6Any](/dotnet/api/system.net.ipaddress.ipv6any) is preferred to [Any](/dotnet/api/system.net.ipaddress.any) because `Any` is less performant than `IPv6Any`. In some cases, `Any` may not work at all. `Any` has performance problems due to the [underlying System types implementation](https://github.com/dotnet/runtime/issues/82404).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phrasing has performance problems is not what I wanted to say - it raises a question of why not fix the System types then? I wanted to avoid this

Copy link
Contributor Author

@Rick-Anderson Rick-Anderson Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phrasing has performance problems is not what I wanted to say - it raises a question of why not fix the System types then? I wanted to avoid this

I've reverted to your wording with my wording. I don't see the difference between slower than necessary and less performant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets also include the info about server machine supporting IPv6 - it is the case where the analyzer should be applied. Its necessary to have this information


At the moment of current article publishing, in case of HTTP/1.x or HTTP/2.0 a name like `localhost` will resolve to `[::1]`, which won't be accepted by the server, forcing a retry with `127.0.0.1` (i.e. failed attempt before each connection).
`127.0.0.1` is the IPv4 loopback address. `::1` is the IPv6 loopback address. `Any` is the wildcard address for IPv4. `IPv6Any` is the wildcard address for IPv6.

Current behavior with with IPv6 when using HTTP/1.x or HTTP/2.0:

* `localhost` resolves to `[::1]`.
* `[::1]` isn't accepted by the server, which forces a retry using `127.0.0.1`, creating a repeated cycle.

Using `Any` with the preceding conditions reports the `ASP0028` diagnostic message:

This usage will be reported with a diagnostic message:
```csharp
.UseKestrel().ConfigureKestrel(options =>
{
Expand All @@ -31,36 +37,32 @@ This usage will be reported with a diagnostic message:

## Rule description

The recommended way is to setup Kestrel to listen on `IPv6Any`.
The recommended way to configure Kestrel to listen for incoming connections on all available `IPv6` network interfaces is with `IPv6Any`.

## How to fix violations

For the reported code
```csharp
.UseKestrel().ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, ...);
})
```
For the problematic code, replace `Any` with `IPv6Any`:

One can either explicitly change usage to `IPv6Any`:
```csharp
```diff
.UseKestrel().ConfigureKestrel(options =>
{
options.Listen(IPAddress.IPv6Any, ...);
- options.Listen(IPAddress.Any, ...);
+ options.Listen(IPAddress.IPv6Any, ...);
})
```

or use another invocation - `options.ListenAnyIP()` without specifying any argument explicitly:
```csharp
Alternatively, use the [ListenAnyIP](https://source.dot.net/#Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerOptions.cs,1c84a7db2c1f6892) method without specifying any arguments:

```diff
.UseKestrel().ConfigureKestrel(options =>
{
options.ListenAnyIP(...);
- options.Listen(IPAddress.Any, ...);
+ options.ListenAnyIP(...);
})
```

## When to suppress warnings

The severity level of this diagnostic is Information. You can suppress warnings if your intention is to disable `IPv6` usage completely on the server.
The `ASP0028` diagnostic has [Information](/dotnet/api/microsoft.extensions.logging.loglevel) level severity. Suppress this warning if your intention is to disable `IPv6` usage completely on the server, although doing so risks the performance problems mentioned in this article.

You can disable IPv6 either system-wide, or for .NET only via the [AppCtx switch or environment variable](https://devblogs.microsoft.com/dotnet/dotnet-6-networking-improvements/#an-option-to-globally-disable-ipv6)
`IPv6` can be disabled either system-wide, or for .NET only via the [AppCtx switch or environment variable](https://devblogs.microsoft.com/dotnet/dotnet-6-networking-improvements/#an-option-to-globally-disable-ipv6)
2 changes: 2 additions & 0 deletions aspnetcore/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,8 @@ items:
uid: diagnostics/asp0025
- name: ASP0026
uid: diagnostics/asp0026
- name: ASP0028
uid: diagnostics/asp0028
- name: BL0001
uid: diagnostics/bl0001
- name: BL0002
Expand Down
Loading