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
2 changes: 1 addition & 1 deletion src/Servers/HttpSys/HttpSysServer.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@
"src\\WebEncoders\\src\\Microsoft.Extensions.WebEncoders.csproj"
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Net;
using Microsoft.AspNetCore.HttpSys.Internal;
using Windows.Win32.Networking.WinSock;
using Xunit;
using static Microsoft.AspNetCore.HttpSys.Internal.SocketAddress;
using SocketAddress = Microsoft.AspNetCore.HttpSys.Internal.SocketAddress;

namespace Microsoft.AspNetCore.Server.HttpSys.Tests.NativeInterop;

public class SocketAddressTests
{
[Theory]
[InlineData(80)]
[InlineData(443)]
[InlineData(8080)]
[InlineData(32767)] // max signed short
[InlineData(32768)] // min value that causes negative when cast to short
[InlineData(42000)]
[InlineData(65535)] // Max port number
public void IPv6_GetPort_ReturnsCorrectPort_ForAllValidPorts(ushort expectedPort)
{
var nativeIpV6Address = new SOCKADDR_IN6
{
sin6_family = ADDRESS_FAMILY.AF_INET6,
sin6_port = (ushort)IPAddress.HostToNetworkOrder((short)expectedPort)
};

var socketAddress = new SocketAddressIPv6(nativeIpV6Address);
var actualPort = socketAddress.GetPort();

Assert.Equal(expectedPort, actualPort);
Assert.True(actualPort >= 0, "Port should never be negative");
Assert.True(actualPort <= 65535, "Port should not exceed maximum valid port");
}

[Theory]
[InlineData(80)]
[InlineData(443)]
[InlineData(8080)]
[InlineData(42000)]
[InlineData(32767)]
[InlineData(32768)]
[InlineData(65535)]
public void IPv4_GetPort_ReturnsCorrectPort_ForAllValidPorts(ushort expectedPort)
{
var nativeIpV4Address = new SOCKADDR_IN
{
sin_family = ADDRESS_FAMILY.AF_INET,
sin_port = (ushort)IPAddress.HostToNetworkOrder((short)expectedPort)
};

var socketAddress = new SocketAddressIPv4(nativeIpV4Address);
var actualPort = socketAddress.GetPort();

Assert.Equal(expectedPort, actualPort);
Assert.True(actualPort >= 0, "Port should never be negative");
Assert.True(actualPort <= 65535, "Port should not exceed maximum valid port");
}
}
17 changes: 11 additions & 6 deletions src/Shared/HttpSys/NativeInterop/SocketAddress.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers.Binary;
using System.Net;
using Windows.Win32.Networking.WinSock;

Expand All @@ -25,7 +26,8 @@ internal abstract class SocketAddress
};
}

private sealed class SocketAddressIPv4 : SocketAddress
// internal for testing
internal sealed class SocketAddressIPv4 : SocketAddress
{
private readonly SOCKADDR_IN _sockaddr;

Expand All @@ -36,8 +38,9 @@ internal SocketAddressIPv4(in SOCKADDR_IN sockaddr)

internal override int GetPort()
{
// sin_port is network byte order
return IPAddress.NetworkToHostOrder((short)_sockaddr.sin_port);
// _sockaddr.sin_port has network byte order.
// cast to ushort is important to avoid negative values for the TCP port
return (ushort)IPAddress.NetworkToHostOrder((short)_sockaddr.sin_port);
}

internal override IPAddress? GetIPAddress()
Expand All @@ -47,7 +50,8 @@ internal override int GetPort()
}
}

private sealed class SocketAddressIPv6 : SocketAddress
// internal for testing
internal sealed class SocketAddressIPv6 : SocketAddress
{
private readonly SOCKADDR_IN6 _sockaddr;

Expand All @@ -58,8 +62,9 @@ internal SocketAddressIPv6(in SOCKADDR_IN6 sockaddr)

internal override int GetPort()
{
// sin6_port is network byte order
return IPAddress.NetworkToHostOrder((short)_sockaddr.sin6_port);
// _sockaddr.sin6_port has network byte order.
// cast to ushort is important to avoid negative values for the TCP port
return (ushort)IPAddress.NetworkToHostOrder((short)_sockaddr.sin6_port);
}

internal override IPAddress? GetIPAddress()
Expand Down
Loading