Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion src/libraries/Common/src/System/Net/IPEndPointExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ public static IPAddress GetIPAddress(ReadOnlySpan<byte> socketAddressBuffer)
Span<byte> address = stackalloc byte[IPAddressParserStatics.IPv6AddressBytes];
uint scope;
SocketAddressPal.GetIPv6Address(socketAddressBuffer, address, out scope);
return new IPAddress(address, (long)scope);

// Clear scope if set for anything but Link Local address (always starts with fe80 first 10bits).
return new IPAddress(address, (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ? (long)scope : 0);
}
else if (family == AddressFamily.InterNetwork)
{
Expand Down
40 changes: 38 additions & 2 deletions src/libraries/Common/tests/System/Net/Configuration.Sockets.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;

namespace System.Net.Test.Common
{
public static partial class Configuration
{
public static partial class Sockets
{
public static Uri SocketServer => GetUriValue("DOTNET_TEST_NET_SOCKETS_SERVERURI", new Uri("http://" + DefaultAzureServer));
public static Uri SocketServer => GetUriValue("DOTNET_TEST_NET_SOCKETS_SERVERURI", new Uri("http://" + DefaultAzureServer));

public static string InvalidHost => GetValue("DOTNET_TEST_NET_SOCKETS_INVALIDSERVER", "notahostname.invalid.corp.microsoft.com");

public static IPAddress? LinkLocalAddress => GetIPv6LinkLocalAddress();

public static IEnumerable<object[]> LocalAddresses()
{
if (LinkLocalAddress != null)
{
yield return new[] { LinkLocalAddress };
}
if (Socket.OSSupportsIPv4)
{
yield return new[] { IPAddress.Loopback };
}
if (Socket.OSSupportsIPv6)
{
yield return new[] { IPAddress.IPv6Loopback };
}
}

public static string InvalidHost => GetValue("DOTNET_TEST_NET_SOCKETS_INVALIDSERVER", "notahostname.invalid.corp.microsoft.com");
private static IPAddress GetIPv6LinkLocalAddress() =>
NetworkInterface
.GetAllNetworkInterfaces()
.Where(i => !i.Description.StartsWith("PANGP Virtual Ethernet")) // This is a VPN adapter, but is reported as a regular Ethernet interface with
// a valid link-local address, but the link-local address doesn't actually work.
// So just manually filter it out.
.Where(i => !i.Name.Contains("Tailscale")) // Same as PANGP above.
.SelectMany(i => i.GetIPProperties().UnicastAddresses)
.Select(a => a.Address)
.Where(a => a.IsIPv6LinkLocal)
.FirstOrDefault();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif
Expand Down Expand Up @@ -168,7 +170,7 @@ public async Task GetAsync_IPv6LinkLocalAddressUri_Success()
using HttpClientHandler handler = CreateHttpClientHandler(allowAllCertificates: true);
using HttpClient client = CreateHttpClient(handler);

var options = new GenericLoopbackOptions { Address = TestHelper.GetIPv6LinkLocalAddress() };
var options = new GenericLoopbackOptions { Address = Configuration.Sockets.LinkLocalAddress };
if (options.Address == null)
{
throw new SkipTestException("Unable to find valid IPv6 LL address.");
Expand Down
14 changes: 0 additions & 14 deletions src/libraries/Common/tests/System/Net/Http/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
Expand Down Expand Up @@ -104,18 +102,6 @@ public static Task WhenAllCompletedOrAnyFailedWithTimeout(int timeoutInMilliseco
public static Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> AllowAllCertificates = (_, __, ___, ____) => true;
#endif

public static IPAddress GetIPv6LinkLocalAddress() =>
NetworkInterface
.GetAllNetworkInterfaces()
.Where(i => !i.Description.StartsWith("PANGP Virtual Ethernet")) // This is a VPN adapter, but is reported as a regular Ethernet interface with
// a valid link-local address, but the link-local address doesn't actually work.
// So just manually filter it out.
.Where(i => !i.Name.Contains("Tailscale")) // Same as PANGP above.
.SelectMany(i => i.GetIPProperties().UnicastAddresses)
.Select(a => a.Address)
.Where(a => a.IsIPv6LinkLocal)
.FirstOrDefault();

public static byte[] GenerateRandomContent(int size)
{
byte[] data = new byte[size];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Net.Test.Common;
using System.Threading.Tasks;

using Microsoft.DotNet.XUnitExtensions;
using Xunit;
using Xunit.Abstractions;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,5 +304,28 @@ public async Task NetworkInterface_LoopbackInterfaceIndex_MatchesReceivedPackets
ipv6 ? NetworkInterface.IPv6LoopbackInterfaceIndex : NetworkInterface.LoopbackInterfaceIndex);
}
}

[ConditionalFact]
public void NetworkInterface_UnicastLLA_ScopeIdSet()
{
bool foundLla = false;
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
IPInterfaceProperties prop = nic.GetIPProperties();
foreach (UnicastIPAddressInformation info in prop.UnicastAddresses)
{
if (info.Address.IsIPv6LinkLocal)
{
foundLla = true;
Assert.NotEqual(0, info.Address.ScopeId);
}
}
}

if (!foundLla)
{
throw new SkipTestException("Did not find any LLA");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@

namespace System.Net.Quic.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

[Collection(nameof(DisableParallelization))]
[ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))]
public sealed class QuicConnectionTests : QuicTestBase
{
const int ExpectedErrorCode = 1234;
public static IEnumerable<object[]> LocalAddresses = Configuration.Sockets.LocalAddresses();

public QuicConnectionTests(ITestOutputHelper output) : base(output) { }

[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task TestConnect(bool ipv6)
[MemberData(nameof(LocalAddresses))]
public async Task TestConnect(IPAddress address)
{
await using QuicListener listener = await CreateQuicListener(ipv6 ? IPAddress.IPv6Loopback : IPAddress.Loopback);
await using QuicListener listener = await CreateQuicListener(address);
Assert.Equal(address, listener.LocalEndPoint.Address);

var options = CreateQuicClientOptions(listener.LocalEndPoint);
ValueTask<QuicConnection> connectTask = CreateQuicConnection(options);
Expand All @@ -35,27 +38,19 @@ public async Task TestConnect(bool ipv6)
await using QuicConnection serverConnection = acceptTask.Result;
await using QuicConnection clientConnection = connectTask.Result;

IgnoreScopeIdIPEndpointComparer endPointComparer = new();
Assert.Equal(listener.LocalEndPoint, serverConnection.LocalEndPoint, endPointComparer);
Assert.Equal(listener.LocalEndPoint, clientConnection.RemoteEndPoint, endPointComparer);
Assert.Equal(clientConnection.LocalEndPoint, serverConnection.RemoteEndPoint, endPointComparer);
Assert.Equal(listener.LocalEndPoint, serverConnection.LocalEndPoint);
Assert.Equal(listener.LocalEndPoint, clientConnection.RemoteEndPoint);
if (PlatformDetection.IsWindows && address.IsIPv6LinkLocal)
{
// https://github.com/microsoft/msquic/issues/3813
Assert.Equal(clientConnection.LocalEndPoint, serverConnection.RemoteEndPoint);
}
Assert.Equal(ApplicationProtocol.ToString(), clientConnection.NegotiatedApplicationProtocol.ToString());
Assert.Equal(ApplicationProtocol.ToString(), serverConnection.NegotiatedApplicationProtocol.ToString());
Assert.Equal(options.ClientAuthenticationOptions.TargetHost, clientConnection.TargetHostName);
Assert.Equal(options.ClientAuthenticationOptions.TargetHost, serverConnection.TargetHostName);
}

private class IgnoreScopeIdIPEndpointComparer : IEqualityComparer<IPEndPoint>
{
public bool Equals(IPEndPoint x, IPEndPoint y)
{
byte[] xBytes = x.Address.GetAddressBytes();
byte[] yBytes = y.Address.GetAddressBytes();
return xBytes.AsSpan().SequenceEqual(yBytes) && x.Port == y.Port;
}
public int GetHashCode([DisallowNull] IPEndPoint obj) => obj.Port;
}

private static async Task<QuicStream> OpenAndUseStreamAsync(QuicConnection c)
{
QuicStream s = await c.OpenOutboundStreamAsync(QuicStreamType.Bidirectional);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<Compile Include="$(CommonTestPath)System\Net\Configuration.Certificates.Dynamic.cs" Link="TestCommon\System\Net\Configuration.Certificates.Dynamic.cs" />
<Compile Include="$(CommonTestPath)System\Net\Configuration.Http.cs" Link="Common\System\Net\Configuration.Http.cs" />
<Compile Include="$(CommonTestPath)System\Net\Configuration.Security.cs" Link="Common\System\Net\Configuration.Security.cs" />
<Compile Include="$(CommonTestPath)System\Net\Configuration.Sockets.cs" Link="Common\System\Net\Configuration.Sockets.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\PlatformSupport.cs" Link="TestCommon\System\Security\Cryptography\PlatformSupport.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\X509Certificates\CertificateAuthority.cs" Link="CommonTest\System\Security\Cryptography\X509Certificates\CertificateAuthority.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\X509Certificates\RevocationResponder.cs" Link="CommonTest\System\Security\Cryptography\X509Certificates\RevocationResponder.cs" />
Expand Down