Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@

using System;
using System.Net;
using System.Net.Internals;
using System.Net.Sockets;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Sys
{
#if SYSTEM_NET_SOCKETS_DLL
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_Socket")]
internal static unsafe partial Error Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, IntPtr* socket);
#endif
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_Socket")]
internal static unsafe partial Error Socket(int addressFamily, int socketType, int protocolType, IntPtr* socket);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ internal static partial class Interop
{
internal static partial class Sys
{
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetIPSocketAddressSizes")]
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetSocketAddressSizes")]
[SuppressGCTransition]
internal static unsafe partial Error GetIPSocketAddressSizes(int* ipv4SocketAddressSize, int* ipv6SocketAddressSize);
internal static partial Error GetSocketAddressSizes(ref int ipv4SocketAddressSize, ref int ipv6SocketAddressSize, ref int udsSocketAddressSize, ref int maxSocketAddressSize);

[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetAddressFamily")]
[SuppressGCTransition]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ internal static partial uint IcmpSendEcho2(SafeCloseIcmpHandle icmpHandle, SafeW

[LibraryImport(Interop.Libraries.IpHlpApi, SetLastError = true)]
internal static unsafe partial uint Icmp6SendEcho2(SafeCloseIcmpHandle icmpHandle, SafeWaitHandle Event, IntPtr apcRoutine, IntPtr apcContext,
byte* sourceSocketAddress, byte[] destSocketAddress, SafeLocalAllocHandle data, ushort dataSize, ref IP_OPTION_INFORMATION options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
Span<byte> sourceSocketAddress, Span<byte> destSocketAddress, SafeLocalAllocHandle data, ushort dataSize, ref IP_OPTION_INFORMATION options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Internals = System.Net.Internals;

internal static partial class Interop
{
Expand Down Expand Up @@ -53,20 +52,14 @@ internal enum GetAdaptersAddressesFlags
}

[StructLayout(LayoutKind.Sequential)]
internal struct IpSocketAddress
internal unsafe struct IpSocketAddress
{
internal IntPtr address;
internal int addressLength;

internal IPAddress MarshalIPAddress()
{
// Determine the address family used to create the IPAddress.
AddressFamily family = (addressLength > Internals.SocketAddress.IPv4AddressSize)
? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork;
Internals.SocketAddress sockAddress = new Internals.SocketAddress(family, addressLength);
Marshal.Copy(address, sockAddress.Buffer, 0, addressLength);

return sockAddress.GetIPAddress();
return IPEndPointExtensions.GetIPAddress(new Span<byte>((void*)address, addressLength));
}
}

Expand Down Expand Up @@ -511,7 +504,7 @@ internal static unsafe partial uint GetAdaptersAddresses(
uint* outBufLen);

[LibraryImport(Interop.Libraries.IpHlpApi)]
internal static unsafe partial uint GetBestInterfaceEx(byte* ipAddress, int* index);
internal static unsafe partial uint GetBestInterfaceEx(Span<byte> ipAddress, int* index);

[LibraryImport(Interop.Libraries.IpHlpApi)]
internal static partial uint GetIfEntry2(ref MibIfRow2 pIfRow);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal static partial class Winsock
[LibraryImport(Interop.Libraries.Ws2_32, SetLastError = true)]
internal static partial SocketError WSAConnect(
SafeSocketHandle socketHandle,
byte[] socketAddress,
Span<byte> socketAddress,
Copy link
Member

@stephentoub stephentoub Aug 1, 2023

Choose a reason for hiding this comment

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

Should we make the actual LibraryImport private, with an internal wrapper that doesn't take socketAddressSize? e.g.

[LibraryImport(Interop.Libraries.Ws2_32, SetLastError = true)]
private static partial SocketError WSAConnect(
    SafeSocketHandle socketHandle,
    Span<byte> socketAddress,
    int socketAddressSize,
    IntPtr inBuffer,
    IntPtr outBuffer,
    IntPtr sQOS,
    IntPtr gQOS);

internal static SocketError WSAConnect(
    SafeSocketHandle socketHandle,
    Span<byte> socketAddress,
    IntPtr inBuffer,
    IntPtr outBuffer,
    IntPtr sQOS,
    IntPtr gQOS) =>
    WSAConnect(socketHandle, socketAddress, socketAddress.Length, inBuffer, outBuffer, sQOS, gQOS);

?

Though reading further that might make it a bit inconsistent with some of the other overloads. It's just a bit strange to see both the span and length passed in.

int socketAddressSize,
IntPtr inBuffer,
IntPtr outBuffer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal static partial class Winsock
[LibraryImport(Interop.Libraries.Ws2_32, SetLastError = true)]
internal static partial IntPtr accept(
SafeSocketHandle socketHandle,
byte[] socketAddress,
Span<byte> socketAddress,
ref int socketAddressSize);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ internal static partial class Winsock
[LibraryImport(Interop.Libraries.Ws2_32, SetLastError = true)]
internal static unsafe partial int recvfrom(
SafeSocketHandle socketHandle,
byte* pinnedBuffer,
Span<byte> pinnedBuffer,
int len,
SocketFlags socketFlags,
byte[] socketAddress,
Span<byte> socketAddress,
ref int socketAddressSize);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal static unsafe partial int sendto(
byte* pinnedBuffer,
int len,
SocketFlags socketFlags,
byte[] socketAddress,
ReadOnlySpan<byte> socketAddress,
int socketAddressSize);
}
}
54 changes: 54 additions & 0 deletions src/libraries/Common/src/System/Net/IPEndPointExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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;

namespace System.Net.Sockets
{
internal static class IPEndPointExtensions
{
public static IPAddress GetIPAddress(ReadOnlySpan<byte> socketAddressBuffer)
{
if (SocketAddressPal.GetAddressFamily(socketAddressBuffer) == AddressFamily.InterNetworkV6)
{
Span<byte> address = stackalloc byte[IPAddressParserStatics.IPv6AddressBytes];
uint scope;
SocketAddressPal.GetIPv6Address(socketAddressBuffer, address, out scope);
return new IPAddress(address, (long)scope);
}

return new IPAddress((long)SocketAddressPal.GetIPv4Address(socketAddressBuffer) & 0x0FFFFFFFF);
}

public static void SetIPAddress(Span<byte> socketAddressBuffer, IPAddress address)
{
SocketAddressPal.SetAddressFamily(socketAddressBuffer, address.AddressFamily);
SocketAddressPal.SetPort(socketAddressBuffer, 0);
if (address.AddressFamily == AddressFamily.InterNetwork)
{
#pragma warning disable CS0618
SocketAddressPal.SetIPv4Address(socketAddressBuffer, (uint)address.Address);
#pragma warning restore CS0618
}
else
{
Span<byte> addressBuffer = stackalloc byte[IPAddressParserStatics.IPv6AddressBytes];
address.TryWriteBytes(addressBuffer, out _);
SocketAddressPal.SetIPv6Address(socketAddressBuffer, addressBuffer, (uint)address.ScopeId);
}
}

public static IPEndPoint CreateIPEndPoint(ReadOnlySpan<byte> socketAddressBuffer)
{
return new IPEndPoint(GetIPAddress(socketAddressBuffer), SocketAddressPal.GetPort(socketAddressBuffer));
}

// https://github.com/dotnet/runtime/issues/78993
public static void Serialize(this IPEndPoint endPoint, Span<byte> destination)
{
SocketAddressPal.SetAddressFamily(destination, endPoint.AddressFamily);
SetIPAddress(destination, endPoint.Address);
SocketAddressPal.SetPort(destination, (ushort)endPoint.Port);
}
}
}
Loading