Skip to content

ReceiveMessageFrom does not work correctly on Linux after altering BufferList to a single buffer #46860

@antonfirsov

Description

@antonfirsov

After setting / using SocketAsyncEventArgs.BufferList we should be able to revert to single-buffer mode by calling:

saea.BufferList = null;
saea.SetBuffer(...);

While working on UDP test harmonization, I discovered that this does not work with ReceiveMessageFrom on Linux. Haven't checked other Unixes.

Repro:

[Fact]
public void ReceiveMessageFromIssue()
{
    using var receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    using var sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    using var saea = new SocketAsyncEventArgs();
    var completed = new ManualResetEventSlim();
    saea.Completed += delegate { completed.Set(); };

    receiver.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    sender.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);

    // Commenting out the following line makes the issue disappear:
    saea.BufferList = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[1]) };

    saea.BufferList = null;
    saea.SetBuffer(new byte[1024], 0, 1024);

    sender.SendTo(new byte[1024], receiver.LocalEndPoint);
    if (receiver.ReceiveMessageFromAsync(saea)) 
        Assert.True(completed.Wait(1000), "Expected operation to complete within timeout");

    // Fails on Linux, works on Windows:
    Assert.Equal(1024, saea.BytesTransferred);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions