-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Remove unneeded 'fixed' statements from SocketAddress #61006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
7b9722f
566ea2f
962015d
221d00a
0ce67cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,96 +1,73 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Diagnostics.Contracts; | ||
| using System.Net; | ||
| using System.Net.Sockets; | ||
| using Windows.Win32.Networking.WinSock; | ||
|
|
||
| namespace Microsoft.AspNetCore.HttpSys.Internal; | ||
|
|
||
| internal sealed class SocketAddress | ||
| internal abstract class SocketAddress | ||
| { | ||
| private const int NumberOfIPv6Labels = 8; | ||
| private const int IPv6AddressSize = 28; | ||
| private const int IPv4AddressSize = 16; | ||
| private const int WriteableOffset = 2; | ||
| internal abstract int GetPort(); | ||
|
|
||
| private readonly byte[] _buffer; | ||
| private readonly int _size; | ||
| internal abstract IPAddress? GetIPAddress(); | ||
|
|
||
| private SocketAddress(AddressFamily family, int size) | ||
| internal static unsafe SocketAddress? CopyOutAddress(SOCKADDR* pSockaddr) | ||
| { | ||
| ArgumentOutOfRangeException.ThrowIfLessThan(size, WriteableOffset); | ||
| Family = family; | ||
| _size = size; | ||
| // Sized to match the native structure | ||
| _buffer = new byte[((size / IntPtr.Size) + 2) * IntPtr.Size]; // sizeof DWORD | ||
| // Per https://learn.microsoft.com/windows/win32/api/ws2def/ns-ws2def-sockaddr, | ||
| // use the SOCKADDR* pointer only to read the address family, then cast the pointer to | ||
| // the appropriate family type and continue processing. | ||
| return pSockaddr->sa_family switch | ||
| { | ||
| ADDRESS_FAMILY.AF_INET => new SocketAddressIPv4(*(SOCKADDR_IN*)pSockaddr), | ||
| ADDRESS_FAMILY.AF_INET6 => new SocketAddressIPv6(*(SOCKADDR_IN6*)pSockaddr), | ||
| _ => null | ||
| }; | ||
| } | ||
|
|
||
| internal AddressFamily Family { get; } | ||
|
|
||
| internal int GetPort() | ||
| private sealed class SocketAddressIPv4 : SocketAddress | ||
| { | ||
| return (_buffer[2] << 8 & 0xFF00) | (_buffer[3]); | ||
| } | ||
| private readonly SOCKADDR_IN _sockaddr; | ||
|
Check failure on line 30 in src/Shared/HttpSys/NativeInterop/SocketAddress.cs
|
||
|
|
||
| internal IPAddress? GetIPAddress() | ||
| { | ||
| if (Family == AddressFamily.InterNetworkV6) | ||
| internal SocketAddressIPv4(in SOCKADDR_IN sockaddr) | ||
|
Check failure on line 32 in src/Shared/HttpSys/NativeInterop/SocketAddress.cs
|
||
| { | ||
| return GetIpv6Address(); | ||
| _sockaddr = sockaddr; | ||
| } | ||
| else if (Family == AddressFamily.InterNetwork) | ||
|
|
||
| internal override int GetPort() | ||
| { | ||
| return GetIPv4Address(); | ||
| // sin_port is network byte order | ||
| return IPAddress.NetworkToHostOrder((short)_sockaddr.sin_port); | ||
| } | ||
| else | ||
|
|
||
| internal override IPAddress? GetIPAddress() | ||
| { | ||
| return null; | ||
| // address is network byte order | ||
| return new IPAddress(_sockaddr.sin_addr.S_un.S_addr); | ||
| } | ||
| } | ||
|
|
||
| private IPAddress GetIpv6Address() | ||
| { | ||
| Contract.Assert(_size >= IPv6AddressSize); | ||
| var bytes = new byte[NumberOfIPv6Labels * 2]; | ||
| Array.Copy(_buffer, 8, bytes, 0, NumberOfIPv6Labels * 2); | ||
| return new IPAddress(bytes); // TODO: Does scope id matter? | ||
| } | ||
|
|
||
| private IPAddress GetIPv4Address() | ||
| private sealed class SocketAddressIPv6 : SocketAddress | ||
| { | ||
| Contract.Assert(_size >= IPv4AddressSize); | ||
| return new IPAddress(new byte[] { _buffer[4], _buffer[5], _buffer[6], _buffer[7] }); | ||
| } | ||
| private readonly SOCKADDR_IN6 _sockaddr; | ||
|
Check failure on line 52 in src/Shared/HttpSys/NativeInterop/SocketAddress.cs
|
||
|
|
||
| internal static unsafe SocketAddress? CopyOutAddress(IntPtr address) | ||
| { | ||
| var addressFamily = *((ushort*)address); | ||
| if (addressFamily == (ushort)AddressFamily.InterNetwork) | ||
| internal SocketAddressIPv6(in SOCKADDR_IN6 sockaddr) | ||
|
Check failure on line 54 in src/Shared/HttpSys/NativeInterop/SocketAddress.cs
|
||
| { | ||
| var v4address = new SocketAddress(AddressFamily.InterNetwork, IPv4AddressSize); | ||
| fixed (byte* pBuffer = v4address._buffer) | ||
| { | ||
| for (var index = 2; index < IPv4AddressSize; index++) | ||
| { | ||
| pBuffer[index] = ((byte*)address)[index]; | ||
| } | ||
| } | ||
| return v4address; | ||
| _sockaddr = sockaddr; | ||
| } | ||
| if (addressFamily == (ushort)AddressFamily.InterNetworkV6) | ||
|
|
||
| internal override int GetPort() | ||
| { | ||
| var v6address = new SocketAddress(AddressFamily.InterNetworkV6, IPv6AddressSize); | ||
| fixed (byte* pBuffer = v6address._buffer) | ||
| { | ||
| for (var index = 2; index < IPv6AddressSize; index++) | ||
| { | ||
| pBuffer[index] = ((byte*)address)[index]; | ||
| } | ||
| } | ||
| return v6address; | ||
| // sin6_port is network byte order | ||
| return IPAddress.NetworkToHostOrder((short)_sockaddr.sin6_port); | ||
| } | ||
|
|
||
| return null; | ||
| internal override IPAddress? GetIPAddress() | ||
| { | ||
| // address is network byte order | ||
| // when CsWin32 gets support for inline arrays, remove 'AsReadOnlySpan' call below. | ||
| // https://github.com/microsoft/CsWin32/issues/1086 | ||
| return new IPAddress(_sockaddr.sin6_addr.u.Byte.AsReadOnlySpan()); // TODO: Does scope id matter? | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IPAddress does accept a scopeId, any reason not to just pass it in? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBH I don't know. The original code didn't pass it in, and I tried to avoid changing the observable behavior in this PR. (The "TODO" comment is copied from the original code.) |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| // https://github.com/microsoft/cswin32 | ||
| Windows.Win32.Networking.HttpServer | ||
| SOCKADDR_IN | ||
| SOCKADDR_IN6 |
Uh oh!
There was an error while loading. Please reload this page.