Skip to content
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

Socket.SendFile() should fail with a consistent exception for connectionless sockets #47472

Closed
antonfirsov opened this issue Jan 26, 2021 · 11 comments · Fixed by #87108
Closed
Labels
area-System.Net.Sockets bug good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@antonfirsov
Copy link
Member

antonfirsov commented Jan 26, 2021

Socket.SendFile() is not supported on Windows, but the exceptions being thrown are not consistent. The first call throws SocketException, while the second attempt leads to NotSupportedException.

Repro

The twice=true case fails:

[Theory]
[InlineData(false)]
[InlineData(true)]
public void UDP_SendFile(bool twice)
{
    string tempFile = Path.GetTempFileName();
    File.WriteAllBytes(tempFile, new byte[128]);

    using var client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    using var listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    listener.BindToAnonymousPort(IPAddress.Loopback);

    client.Connect(listener.LocalEndPoint);

    Assert.Throws<SocketException>(() => client.SendFile(tempFile));
    if (twice)
    {
        Assert.Throws<SocketException>(() => client.SendFile(tempFile)); // Throws NotSupportedException
    }
}

Edit (after discussion below)

On Linux the call does not fail. We should fail NotSupportedException for connectionless sockets on all OS-es in all cases.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Net.Sockets untriaged New issue has not been triaged by the area owner labels Jan 26, 2021
@ghost
Copy link

ghost commented Jan 26, 2021

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

Issue Details

Socket.SendFile() is not supported on Windows, but the exceptions being thrown are not consistent. The first call throws SocketException, while the second attempt leads to NotSupportedException.

Repro

The twice=true case fails:

[Theory]
[InlineData(false)]
[InlineData(true)]
public void UDP_SendFile(bool twice)
{
    string tempFile = Path.GetTempFileName();
    File.WriteAllBytes(tempFile, new byte[128]);

    using var client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    using var listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    listener.BindToAnonymousPort(IPAddress.Loopback);

    client.Connect(listener.LocalEndPoint);

    Assert.Throws<SocketException>(() => client.SendFile(tempFile));
    if (twice)
    {
        Assert.Throws<SocketException>(() => client.SendFile(tempFile)); // Throws NotSupportedException
    }
}
Author: antonfirsov
Assignees: -
Labels:

area-System.Net.Sockets, untriaged

Milestone: -

@geoffkizer
Copy link
Contributor

What do we do on Linux?

@geoffkizer
Copy link
Contributor

related: #47287

@antonfirsov
Copy link
Member Author

It does not throw. Maybe sendfile just works on Linux with UDP?

@antonfirsov antonfirsov changed the title Windows: Socket.SendFile() for throws inconsistent exceptions with UDP Windows: Socket.SendFile() throws inconsistent exceptions with UDP Jan 26, 2021
antonfirsov added a commit to antonfirsov/runtime that referenced this issue Jan 26, 2021
@gfoidl
Copy link
Member

gfoidl commented Jan 26, 2021

From the manpage:

sendfile() copies data between one file descriptor and another.

This doesn't exclude UDP, so on linux it should work?

@wfurt
Copy link
Member

wfurt commented Jan 26, 2021

of course with UDP, there is no way to now if what was sent is what was received. It would just blast content of the file without any feedback,

@antonfirsov
Copy link
Member Author

I also think so (would be nice to double-check with a small app or test).

On Windows, it would be nice to throw consistent exceptions.

I wonder if we should explicitly invest efforts to document these platform differences better, or are these corner cases we don't care about much, since we don't expect users to meet them?

@geoffkizer
Copy link
Contributor

Using SendFile with UDP doesn't really make much sense. The point of SendFile is to send large-ish files efficiently. Max size of a UDP packet is ~1500 bytes. It would be really weird to use SendFile with UDP.

Additionally, on Linux, the platform sendfile() API itself doesn't support pre and post buffers -- it just takes a fd. So we mimic the Windows behavior by sending the pre and post buffers manually using send(). But if you are using UDP, this probably isn't what you want -- the pre and post buffers will end up getting sent in different packets.

As such, I think we should just fail if you try to do SendFile on UDP for both Linux and Windows. The fact that this doesn't fail on Linux today is really an oversight.

Also, it seems fine to just always throw NotSupportedException here.

@antonfirsov antonfirsov changed the title Windows: Socket.SendFile() throws inconsistent exceptions with UDP Socket.SendFile() should fail with a consistent exception for connectionless sockets Jan 27, 2021
@antonfirsov
Copy link
Member Author

Seems like we agree on this, I repurposed the issue based on the discussion outcome.

@ManickaP
Copy link
Member

Triage: to keep is consistent we should throw on Linux, we should fix this for 6.0 until someone depends on not throwing.

@ManickaP ManickaP removed the untriaged New issue has not been triaged by the area owner label Feb 18, 2021
@ManickaP ManickaP added this to the 6.0.0 milestone Feb 18, 2021
@karelz
Copy link
Member

karelz commented May 13, 2021

Triage: Not a regression, UDP -- low usage. Fine to move to Future.

@karelz karelz modified the milestones: 6.0.0, Future May 13, 2021
@karelz karelz added the bug label May 13, 2021
@wfurt wfurt added help wanted [up-for-grabs] Good issue for external contributors good first issue Issue should be easy to implement, good for first-time contributors labels Jan 25, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jun 4, 2023
@ghost ghost added in-pr There is an active PR which will close this issue when it is merged and removed in-pr There is an active PR which will close this issue when it is merged labels Aug 8, 2023
MihaZupan pushed a commit that referenced this issue Aug 9, 2023
…less sockets (#87108)

* Unified to throw NotSupportedException when SendFile() for connectionless sockets

The issue was that the Socket.SendFile() threw inconsistent exceptions when the platform was Windows and the protocol was UDP.
The first call would throw a SocketException, while the second call would throw a NotSupportedException.

With this commit, SendFile() will consistently throw NotSupportException on all platforms when the protocol is UDP.

Fix #47472

* Change to throws `NotSupportedException` if `!IsConnectionOriented` or `!Connected`.

Before:.

    Throws `NotSupportedException` on UDP.

After:

    Throws `NotSupportedException` if `!IsConnectionOriented` or `!Connected`.

* Changed test case `UdpConnection_ThrowsException` to run regardless of platform.

* Update src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs

Co-authored-by: Karel Zikmund <karelz@microsoft.com>

---------

Co-authored-by: Karel Zikmund <karelz@microsoft.com>
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 9, 2023
@karelz karelz modified the milestones: Future, 8.0.0 Aug 10, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Sep 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Sockets bug good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants