none
System.Net.Sockets.Socket.ReceiveMessageFromAsync (at least) does not correctly fill the IPPacketInformation when an IPv4 packet is received by a dual mode raw socket RRS feed

  • Question

  • Steps to reproduce (.NET Framework 4.6.1):

    1. Create a dual RAW socket (in the example, for SCTP), either by:

    var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Raw, (ProtocolType)132); // SCTP
    socket.DualMode = true;
    socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
    socket.Bind(new IPEndPoint(IPAddress.IPv6Any, 0));

    or:

    var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Raw, (ProtocolType)132); // SCTP
    socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
    socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
    socket.Bind(new IPEndPoint(IPAddress.IPv6Any, 0))

    2. Create a SocketAsyncEventArgs for the receiver and enqueue a ReceiveMessageFrom operation:

    var socketAsyncEventArgs = new SocketAsyncEventArgs(); socketAsyncEventArgs.SetBuffer(new byte[ushort.MaxValue], 0, ushort.MaxValue);

    socketAsyncEventArgs.Completed += (sender, e) { if (e.SocketError == SocketError.Success) { var packetInformation = e.ReceiveMessageFromPacketInfo; // Use the packetInformation... } } socketAsyncEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Any, 0); socket.ReceiveMessageFromAsync(socketAsyncEventArgs); // For this example, assume ReceiveMessageFromAsync returns true, i.e., the operation completes asynchronously.

    3. Result when an IPv4 packet is received:

    3.1 Expected: Either packetInformation.Address contains an IPAddress with AddressFamily equal to InterNetwork or an IPv6 mapped IPv4 address (AddressFamily equal to InterNetworkV6). Moreover, packetInformation.Address and packetInformation.Interface are correct.

    3.2. Actual: packetInformation.Address is an IPv6 address (AddressFamily equal to InterNetworkV6) with its first 4 bytes (out of 16) equal to the 4 bytes of the destination IPv4 address, and the 5th byte equal to the interface index, whereas packetInformation.Interface equals 0. Unusable and nonsense. The Address reserved buffer is filled with address plus interface, which results in incorrect Address and incorrect Interface. Cannot resort to IPv4 header parsing in this case, because .NET/Winsock does not deterministically tell you that the packet is IPv4.

    I must be doing something wrong, because it's hard to believe such a big bug has gone unnoticed for so long.

    My only alternative is using two sockets (one for IPv4 and one for IPv6) instead of a dual mode one.

    Can you confirm whether this is a known bug or there is something missing in my socket setup?

    Thank you very much.


    P.S: I also don't understand the test code in ReceiveMessageFrom_Helper in https://github.com/dotnet/corefx/blob/master/src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs. Specifically, the line:

    Assert.Equal(connectTo, ipPacketInformation.Address);
    Because connectTo is the remote address, and my own tests suggest that ipPacketInformation.Address contains the converse address to remoteEndPoint.Address, i.e., in ReceiveMessageFrom_Helper, listenOn. What I mean is the test should always fail unless listenOn and connectTo are equal.







    Monday, December 3, 2018 5:21 PM

All replies

  • Hi mulhacén,

    Thank you for posting here.

    To further help you about this issue, I am trying to invoke someone experienced to help look into this thread, this may take some time and as soon as we get any result, we will post back.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, December 5, 2018 8:39 AM
    Moderator
  • Hi,

    For packet information, you can refer this document and this blog.

    For issue related to Github dotnet/corefx repo, you can submit an issue here to get direct support.

    I will update if I find other resources, you can also provide a testable demo for us to test your issue.

    Best Regards,

    Charles


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, December 7, 2018 10:14 AM