-
-
Notifications
You must be signed in to change notification settings - Fork 416
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
Don't silence errors from quinn-udp
code
#1971
Comments
I'm not sure exposing more errors is useful. The motivation behind the current behavior is that UDP network errors are almost invariably one of two cases: those that can be trivially spoofed by an attacker, and those that may be transient. For example, do you want to disable your socket just because the user's wifi drops out for a moment, or they changed networks? |
We don't hard-fail in our app for any IO errors for exactly that reason :) As far as I know, I am test-driving a change in a fork right now. I can report how that is going in a couple of days! In general though, I think it wouldn't hurt to expose the errors at this layer. It gives more flexibility to users which makes it IMO a better library. |
"Permanent until it changes" isn't very permanent. Further, if your socket is bound to the wildcard address, as typical, there's no point recreating it in response to network changes. Detecting network changes is also difficult, especially in portable code.
There needs to be a concrete use case that outweighs the footgun and which doesn't have a similar or better solution elsewhere.
Interpreting this as a fatal condition in particular seems like a mistake, because "any kind of packet" isn't quite right. What if someone wants to communicate with a link-local peer? |
There is. On MacOS, a socket bound to the wildcard address will not be able to use newly attached interfaces.
If there is a route (to a link-local peer), then the syscall isn't going to fail with
I agree with you in principle but what is the footgun that you are seeing here? Anybody building applications on top of UDP will be aware that failure to send an individual packet isn't necessarily fatal to their application. If anything, I'd consider the decision to not expose errors a footgun because it deviates from what tokio's and std's UDP socket do. |
To be clear, if we decide to change this, then I'll obviously move the current behaviour up into |
What, really? Is that documented anywhere? That makes it much harder to make a well-behaved client application...
It will if you try to communicate with someone else concurrently, at least.
I'm not sure that's true. It wasn't obvious to us when we started Quinn, and it will certainly be a surprise to any existing users of quinn-udp. |
Yep, welcome to the world of cross-platform networking 🙃 I'd have to dig through our issues to see if I can find something but that is the behaviour we observed. Hence our application rebinds all sockets when the OS notifies us about a network change event.
Fair enough. This kind of is a case for exposing the errors though. An application that needs to talk to link-local peers and to the wider network would probably want to know that most of its packets are failing to send. In any case, such an application will have strictly more context to make a good decision on how to handle errors compared to the socket library.
Communicating such a change can easily be done by breaking / deprecating the API purposely and thus causing compile errors for all existing users. I am not sure what else to argue 🤷♂️
|
This is a good point. I think the error handling of Being able to discard that server immediately gives a much better UX than having to rely on a (series of) timeouts before it is marked as unresponsive. |
This addresses my concern, though it'll be a shame to have to move away from the nice clear
In the spirit of unlocking at least hypothetically better application behavior, I agree that this would be nice to have. Happy to review a PR. |
Just to be clear, the scope we are talking about is:
|
To avoid unpleasant surprises for downstream, I think should introduce a new function rather than drastically changing the semantics of the current one. Open to other ideas, though. |
|
Sure. And presumably a recv version, too? |
I hadn't looked at |
|
Actually, looks like we don't suppress recv errors at all, so probably no changes needed there. |
Should I change the error type of |
If we're going to add |
The current type-signature is very misleading because it is too "wide" and at the same time very common for networking code, meaning pretty much everyone using this API will assume that most impl WouldBlock {
pub fn into_io_error(self) -> std::io::Error {
std::io::ErrorKind::WouldBlock.into()
}
} Most users will use this with something like self.inner.try_io(Interest::WRITABLE, || {
self.state.send((&self.inner).into(), &transmit).map_err(quinn_udp::WouldBlock::into_io_error)
}) We can provide a I am busy with other things this week but I am hoping to be able to send a PR soon after. |
Currently,
quinn-udp
logs certain errors and returnsOk(())
even if the packet did not get sent. For example, a common one we see isThis happens when we have an IPv6 interface but only with a link-local address. Thus, binding the socket to the unspecified address works but sending any kind of packet fails.
I would like to catch this in my application and disable the socket but I cannot because
quinn-udp
returnsOk(())
.Would you be willing to change this? It appears that ignoring a send error within library code is too opinionated and perhaps a layer above (
quinn
itself) would be better suited for this.Note that I am not using
quinn
, we only usequinn-udp
as a socket library.Related: #1750.
The text was updated successfully, but these errors were encountered: