Skip to content

Socket ConnectAsync returns successfully with a non-connected socket if canceled #75889

@bentoi

Description

@bentoi

Description

Socket.ConnetAsync sporadically returns successfully but the socket is not connected (Socket.Connected == false). This occurs when canceling ConnectAsync while it's in progress after the server side accepts the socket.

Reproduction Steps

using System.Net;
using System.Net.Sockets;

while (true)
{
    using var serverSocket =  new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    serverSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    serverSocket.Listen();

    using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    using var cts = new CancellationTokenSource();

    ValueTask connectTask = socket.ConnectAsync(serverSocket.LocalEndPoint!, cts.Token);
    using var _ = await serverSocket.AcceptAsync();
    cts.Cancel();

    try
    {
        await connectTask;
        if (!socket.Connected)
        {
            Console.Error.WriteLine("unexpected non-connected socket after successfull ConnectAsync");
            return 1;
        }
    }
    catch (OperationCanceledException)
    {
        // Expected if canceled before connect.
    }
}

Expected behavior

The ConnectAsync call should either throw OperationCanceledException or return a connected socket.

Actual behavior

ConnectAsync returns but the socket is not connected

Regression?

No response

Known Workarounds

No response

Configuration

.NET Core 6
Linux Debian Buster and macOS

Other information

No response

Activity

ghost added
untriagedNew issue has not been triaged by the area owner
on Sep 20, 2022
ghost

ghost commented on Sep 20, 2022

@ghost

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Socket.ConnetAsync sporadically returns successfully but the socket is not connected (Socket.Connected == false). This occurs when canceling ConnectAsync while it's in progress after the server side accepts the socket.

Reproduction Steps

using System.Net;
using System.Net.Sockets;

while (true)
{
    using var serverSocket =  new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    serverSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    serverSocket.Listen();

    using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    using var cts = new CancellationTokenSource();

    ValueTask connectTask = socket.ConnectAsync(serverSocket.LocalEndPoint!, cts.Token);
    using var _ = await serverSocket.AcceptAsync();
    cts.Cancel();

    try
    {
        await connectTask;
        if (!socket.Connected)
        {
            Console.Error.WriteLine("unexpected non-connected socket after successfull ConnectAsync");
            return 1;
        }
    }
    catch (OperationCanceledException)
    {
        // Expected if canceled before connect.
    }
}

Expected behavior

The ConnectAsync call should either throw OperationCanceledException or return a connected socket.

Actual behavior

ConnectAsync returns but the socket is not connected

Regression?

No response

Known Workarounds

No response

Configuration

.NET Core 6
Linux Debian Buster and macOS

Other information

No response

Author: bentoi
Assignees: -
Labels:

area-System.Net.Sockets

Milestone: -
wfurt

wfurt commented on Sep 20, 2022

@wfurt
Member

I think on macOS this can happen when peer closes the connection. Can you perhaps post complete repro @bentoi that has both sides?

bentoi

bentoi commented on Sep 21, 2022

@bentoi
Author

It has both sides already. The test case creates a server socket to accept connections over the loopback interface. The accepted server socket is not disposed while the client socket connection establishment is in progress or canceled. Not that this occurs on both Linux and macOS. I didn't get a chance to check Windows.

liveans

liveans commented on Sep 27, 2022

@liveans
Member

I was able to reproduce the issue in main, .NET 7.0, 6.0 and 5.0. I think it should be easy to fix. Not critical. We can investigate it more deeply.

karelz

karelz commented on Sep 29, 2022

@karelz
Member

Triage: It is unpleasant behavior, however, it is the only report in last few years (it is an edge case scenario).

added this to the Future milestone on Sep 29, 2022
ghost removed
untriagedNew issue has not been triaged by the area owner
on Sep 29, 2022
kaiohenrique

kaiohenrique commented on Jul 11, 2024

@kaiohenrique

Hi. With a slightly different repro, I have been able to get disposed Sockets in Connected=true state. Could this be a potential socket leaking case?

using System.Net;
using System.Net.Sockets;
using System.Reflection;

var disposedProperty = typeof(Socket).GetProperty("Disposed", BindingFlags.NonPublic | BindingFlags.Instance);

while (true)
{
    using var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    serverSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    serverSocket.Listen();

    using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    using var cts = new CancellationTokenSource();

    ValueTask connectTask = socket.ConnectAsync(serverSocket.LocalEndPoint!, cts.Token);
    using var _ = await serverSocket.AcceptAsync();
    cts.Cancel();
    
    try
    {
        await connectTask;
        var disposed = (bool)disposedProperty.GetValue(socket);
        if (disposed && socket.Connected)
        {
            Console.WriteLine($"Disposed and Connected");
        }
    }
    catch (Exception e)
    {
     
    }
}
modified the milestones: Future, 10.0.0 on Oct 7, 2024
added
in-prThere is an active PR which will close this issue when it is merged
on Jun 23, 2025
self-assigned this
on Jul 1, 2025
added a commit that references this issue on Jul 16, 2025
0a46acc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area-System.Net.Socketsin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Relationships

None yet

    Development

    Participants

    @karelz@kaiohenrique@antonfirsov@bentoi@wfurt

    Issue actions

      Socket ConnectAsync returns successfully with a non-connected socket if canceled · Issue #75889 · dotnet/runtime