dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.36k stars 4.75k forks source link

Icmp only triggers when socket is disposed #108984

Open vsfeedback opened 1 month ago

vsfeedback commented 1 month ago

This issue has been moved from a ticket on Developer Community.


I have noticed that endreceive only gets called when the socket disposes this will trigger

try
{
    using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
    socket. Blocking = true;
    socket. Bind(new IPEndPoint(_address, 0));
    socket. BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref remoteEndPoint, (IAsyncResult ar)=>{ 

Interlocked.Increment(ref _received);                
    }, null);
    _logger?. Lazy(). LogInformation("BeginReceiveFrom called successfully");
}
catch (SocketException ex)
{
    _logger?. LogError("SocketException in BeginReceiveFrom: {0}", ex. Message);
}
catch (Exception ex)
{
    _logger?. LogError("Exception in BeginReceiveFrom: {0}", ex. Message);
}

reading the data from the below code would work as the socket doesn't get disposed, however it never fires.

try
{
    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
    socket. Blocking = true;
    socket. Bind(new IPEndPoint(_address, 0));
    socket. BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref remoteEndPoint, (IAsyncResult ar)=>{ 

Interlocked.Increment(ref _received);                
    }, null);
    _logger?. Lazy(). LogInformation("BeginReceiveFrom called successfully");
}
catch (SocketException ex)
{
    _logger?. LogError("SocketException in BeginReceiveFrom: {0}", ex. Message);
}
catch (Exception ex)
{
    _logger?. LogError("Exception in BeginReceiveFrom: {0}", ex. Message);
}

When looking at the documentation: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.beginreceivefrom?view=net-8.0

and using the Async method I have the error that it awaits only to throw the error that the socket is exposed.

How to use Icmp with .net?


Original Comments

Alison Jin [MSFT] on 8/8/2024, 11:14 PM:

Thank you for your feedback! Does this reproduce for all project or the specific project? If it reproduces with the specific project, what kind of project it is (C#/C++ Console App, WinForms, WPF, AspNet, etc…)? Could you please provide a sample solution that has this problem so that we can conduct further research? It would be very helpful if you could provide some screenshots of this issue. Thanks for your help!

We look forward to hearing from you!

walter.verhoeven on 8/9/2024, 02:51 AM:

yes, copy the code in any project and add a IP address local to the device and the issue is reproducible

Feedback Bot on 8/15/2024, 03:14 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

Radek Zikmund [MSFT] on 8/20/2024, 07:25 AM:

Hi, the sockets functionality exposed in .NET may behave slightly differently based on the platform you are running. You can read about Windows specifics at https://learn.microsoft.com/en-us/windows/win32/winsock/tcp-ip-raw-sockets-2.

I was successfully able to receive ICMP message using your second example (the one without using) using following code

    var socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
    socket2.SendTo(new byte[10], new IPEndPoint(_address, 0));

note that applications may require elevated privilege in order to send data on raw sockets.

Let me know if you have other questions.

dotnet-policy-service[bot] commented 1 month ago

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