Skip to content

Rewrite Socket.ConnectAsync for DNS with async/await #43661

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

Merged
merged 2 commits into from
Oct 27, 2020
Merged
Changes from 1 commit
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
Next Next commit
Avoid several WildcardBindForConnectIfNecessary allocations on each c…
…onnect
  • Loading branch information
stephentoub committed Oct 27, 2020
commit 8ac5dc843a6b5bb83374a186a3cbbe49287fc3a1
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,25 @@ namespace System.Net.Sockets
{
public partial class Socket
{
private static CachedSerializedEndPoint? s_cachedAnyEndPoint;
private static CachedSerializedEndPoint? s_cachedAnyV6EndPoint;
private static CachedSerializedEndPoint? s_cachedMappedAnyV6EndPoint;
private DynamicWinsockMethods? _dynamicWinsockMethods;

internal void ReplaceHandleIfNecessaryAfterFailedConnect() { /* nop on Windows */ }

private sealed class CachedSerializedEndPoint
{
public readonly IPEndPoint IPEndPoint;
public readonly Internals.SocketAddress SocketAddress;

public CachedSerializedEndPoint(IPAddress address)
{
IPEndPoint = new IPEndPoint(address, 0);
SocketAddress = IPEndPointExtensions.Serialize(IPEndPoint);
}
}

[SupportedOSPlatform("windows")]
public Socket(SocketInformation socketInformation)
{
Expand Down Expand Up @@ -223,25 +238,26 @@ partial void WildcardBindForConnectIfNecessary(AddressFamily addressFamily)

// The socket must be bound before using ConnectEx.

IPAddress address;
CachedSerializedEndPoint csep;
switch (addressFamily)
{
case AddressFamily.InterNetwork:
address = IsDualMode ? s_IPAddressAnyMapToIPv6 : IPAddress.Any;
csep = IsDualMode ?
s_cachedMappedAnyV6EndPoint ??= new CachedSerializedEndPoint(s_IPAddressAnyMapToIPv6) :
s_cachedAnyEndPoint ??= new CachedSerializedEndPoint(IPAddress.Any);
break;

case AddressFamily.InterNetworkV6:
address = IPAddress.IPv6Any;
csep = s_cachedAnyV6EndPoint ??= new CachedSerializedEndPoint(IPAddress.IPv6Any);
break;

default:
return;
}

if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, address);
if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, csep.IPEndPoint);

var endPoint = new IPEndPoint(address, 0);
DoBind(endPoint, IPEndPointExtensions.Serialize(endPoint));
DoBind(csep.IPEndPoint, csep.SocketAddress);
}

internal unsafe bool ConnectEx(SafeSocketHandle socketHandle,
Expand Down