News for hackers. Stuff that matters.
Re:Never* Use Datagrams by adunk on Sunday June 23, 2024 @06:59AM (#40766488)
This may seem like a minor nit, but I think there is a problem with using the term "unreliable" to describe UDP. The more commonly used term, and IMHO better term, is "best-effort" [1]. UDP makes its best effort to deliver the datagrams, but the datagrams may be dropped anyway. But it does not make UDP inherently unreliable.

[1] https://en.wikipedia.org/wiki/Best-effort_delivery

Re:Never* Use Datagrams by vitus on Sunday June 23, 2024 @07:17AM (#40766562)
IMO "best-effort" is euphemistic and confusing to people outside of this space, even (especially?) to native English speakers. (I would probably have described UDP as "reasonable effort" and TCP as "best effort", if not for the existing terminology.)

I recall my computer networking professor describing this as "Best-effort means never having to say you're sorry". In practice, best-effort does not mean you try your hardest to make sure the message gets from A to B, it means that you made an effort. Router in the path was congested? Link flap leading to blackholing on the order of 50ms before fast reroute kicks in? Oh well, we tried.

Meanwhile, TCP's reliable delivery will retry several times and will present an in-order data stream to the application.

Reliable vs unreliable might be bad terminology, but I don't think best-effort is any better.

My experience with unreliable systems is that they're great something like 95% of the time, and they're great for raw throughput, but there are many cases where that last 5% makes a huge difference.

Re:Never* Use Datagrams by eru on Sunday June 23, 2024 @08:40AM (#40767033)
The question is 'who deals with dropped packages'? In TCP, the answer is: 'the protocol'. In UDP the answer is 'the next layer of abstraction' (eg the app or some library).

You can build a 'reliable' protocol on top of UDP, and still not get TCP.

Eg if you want to transfer a large file that you know up front, then TCP's streaming mechanism doesn't make too much sense. You could use something like UDP to send the whole file from A to B in little chunks once, and at the end B can tell A what (numbered) chunks she's missing.

There's no reason to hold off on sending chunk n+1 of the file, just because chunk n hasn't arrived yet.

Re:Never* Use Datagrams by vitus on Sunday June 23, 2024 @10:50AM (#40767855)
> There's no reason to hold off on sending chunk n+1 of the file, just because chunk n hasn't arrived yet.

Congestion control comes to mind -- you don't necessarily know what rate the network supports if you don't have a feedback mechanism to let you know when you're sending too fast. Congestion control is one of those things where sure, you can individually cheat and possibly achieve better performance at everyone else's expense, but if everyone does it, then you'll run into congestive collapse.

> You can build a 'reliable' protocol on top of UDP, and still not get TCP.

I agree -- there are reliable protocols running on top of UDP (e.g. QUIC, SCTP) that do not behave exactly like TCP. You don't need an in-order stream in the described use case of bulk file transfer. You certainly don't need head-of-line blocking.

But there are many details and interactions that you and I wouldn't realize or get right on the first try. I would rather not relearn all of those lessons from the past 50+ years.

Re:Never* Use Datagrams by eru on Monday June 24, 2024 @01:35AM (#40772870)
> But there are many details and interactions that you and I wouldn't realize or get right on the first try. I would rather not relearn all of those lessons from the past 50+ years.

Oh, the model I had in mind was not that everyone should write their network code from scratch all the time, but rather that everything that's higher level than datagrams should be handled by unprivileged library code instead of privileged kernel level code.

If speed is an issue, modern Linux can do wonders with eBPF and io_uring, I guess? I'm taking my inspiration from the exokernel folks who believed that abstractions have no place in the operating system kernel.

Re:Never* Use Datagrams by markhahn on Monday June 24, 2024 @02:53PM (#40779424)
interestingly, the exokernel approach is suited to particular cases. for instance, a single application (regardless of whether it's multiple sessions, diversity of RTT, etc). after all, "get the packets into userspace with as little fuss as possible" would be the right goal there.

the unix model is different: it's basically premised on a minicomputer server which would be running a diverse set of independent services where isolation is desired, and where it makes sense for a privileged entity to provide standardized services. services whose API has been both stable and efficient for more than a couple decades.

I think it's kind of like cloud: outsourcing that makes sense at the lower-scale of hosting alternatives. but once you get to a particular scale, you can and should take everything into your own hands, and can expect to obtain some greater efficiency, agility, autonomy.

Re:Never* Use Datagrams by eru on Tuesday June 25, 2024 @12:23AM (#40784460)
> the unix model is different: it's basically premised on a minicomputer server which would be running a diverse set of independent services where isolation is desired, [...]

Exokernels provide isolation. Secure multiplexing is actually the only thing they do.

> and where it makes sense for a privileged entity to provide standardized services. services whose API has been both stable and efficient for more than a couple decades.

Yes, standardisation is great. Libraries can do that standardisation. Why do you need standardisation at the kernel level?

That kind of standardisation is eg what we are doing with libc: memcpy has a stable interface, but how it's implemented depends on the underlying hardware; the kernel does not impose an abstraction.

Re:Never* Use Datagrams by atombender on Sunday June 23, 2024 @11:06AM (#40767995)
Is there a popular protocol that uses this scheme today? I've often thought that this would be a superior way to transfer/sync data. and have always wondered why it wasn't common.

The closest I can think of is the old FSP protocol, which never really saw wide use. The client would request each individual chunk by offset, and if a chunk got lost, it could re-request it. But that's not quite the same thing.

Re:Never* Use Datagrams by 01HNNWZ0MV43FF on Sunday June 23, 2024 @07:14PM (#40771428)
Bittorrent?
Re:Never* Use Datagrams by atombender on Monday June 24, 2024 @05:19AM (#40773940)
BitTorrent is TCP; only the tracker announce protocol is UDP.
Re:Never* Use Datagrams by lxgr on Sunday June 23, 2024 @10:55AM (#40767898)
TCP kind of supports that with selective acknowledgements these days, I think.
Re:Never* Use Datagrams by vitus on Sunday June 23, 2024 @11:03AM (#40767975)
SACKs have been in TCP for 25-30 years now (Widely adopted as part of New Reno, although RFC 2018 proposed the TCP option and implementation back in 1996).

That said, the typical reason why TCP doesn't send packet N+1 is because its congestion window is full.

There is a related problem known as head-of-line blocking where the application won't receive packet N+1 from the kernel until packet N has been received, as a consequence of TCP delivering that in-order stream of bytes.

Re:Never* Use Datagrams by eru on Monday June 24, 2024 @08:33PM (#40782884)
Sorry, I didn't literally mean n+1. What I mean is probably better described by 'head of line blocking'.

Basically, when transmitting a file, in principle you could just keep sending n+k, even if the n-th package hasn't been received or has been dropped. No matter how large k is.

You can take your sweet time fixing the missing packages in the middle, as long as the overall file transfer doesn't get delayed.

Re:Never* Use Datagrams by kazinator on Sunday June 23, 2024 @07:46AM (#40766717)
The term "best effort delivery" in networking is a weasel term that is no better than "unreliable". It should probably be burned.

"Effort" generally refers to some sort of persistence in the face of difficulty. Dropping a packet upon encountering a resource problem isn't effort, let alone best effort.

The way "best effort" is used in networking is quite at odds with the "best efforts" legal/business term, which denotes something short of a firm commitment, but not outright flaking off.

Separately from the delivery question, the checksums in UDP (and TCP!) also poorly assure integrity when datagrams are delivered. They only somewhat improve on the hardware.

Re:Never* Use Datagrams by lxgr on Sunday June 23, 2024 @10:59AM (#40767931)
> Dropping a packet upon encountering a resource problem isn't effort, let alone best effort

The dropping part isn’t the effort; the forwarding part is.

> the checksums in UDP (and TCP!) also poorly assure integrity when datagrams are delivered.

That’s true, but it’s becoming less of a problem with ubiquitous encryption these days (at least on WAN connections).

Re:Never* Use Datagrams by kazinator on Monday June 24, 2024 @05:18AM (#40773927)
I mean that in the same rhetorical sense of "standing around leaning on your shovel isn't effort, let alone best effort". Of course we all understand that what is effort is digging the ditch.

Anyway, so the question is, if typical IP forwarding is "best effort" ... what is an example of poor effort, and what exhibits it?

Re:Never* Use Datagrams by 01HNNWZ0MV43FF on Sunday June 23, 2024 @07:22PM (#40771462)
Should be "at most once" and "at least once", it's already used in other distributed systems with the same kind of problem
Re:Never* Use Datagrams by lll-o-lll on Sunday June 23, 2024 @08:03AM (#40766800)
We’ve been calling it “unreliable” transport since the 80’s, and that’s what it is. Want your packets to get there? TCP. Don’t care much? UDP.

Oversimplified.

Best effort is a dumb term. There’s no effort.

Re:Never* Use Datagrams by eptcyka on Sunday June 23, 2024 @08:14AM (#40766858)
TCP wont always deliver your packets anyway , but it does have a mechanism of timing out if a party believes the other party did not receive something. UDP just means that if one cares for their data to be received, they must verify it themselves.
Re:Never* Use Datagrams by eru on Sunday June 23, 2024 @08:41AM (#40767045)
Yes, it's not so much 'reliable' or 'best effort', rather the difference is 'which part of your software stack should deal with dropped packages'?
Re:Never* Use Datagrams by 13415 on Sunday June 23, 2024 @08:46AM (#40767075)
That's in my opinion what reliable / unrealiable mean in this context.

reliable = it either succeeds or you get an error after some time, unreliable = it may or may not succeed

I concur with the people who think "best effort" is not a good term. But perhaps TCP streams are not reliable enough for TCP to be rightly called a reliable stream protocol. As it turned out, it's not really possible to use TCP without a control channel, message chunking, and similar mechanisms for transmitting arbitrary large files. If it really offered reliable streams that would its primary use case.

Re:Never* Use Datagrams by convolvatron on Sunday June 23, 2024 @09:19AM (#40767279)
the designers of link layers and protocol implemntations, the army of operators who test signals, insteall repeaters, configure routers and hold conferences about how to manage the global routing system would disagree.

best effort implies 'no, we're not going to be climb that curve and get try to get to 100% reliability, because that would actually be counterproductive from an engineering perspective, but we're going to go to pretty substantial lengths to deliver your packet'

Re:Never* Use Datagrams by lxgr on Sunday June 23, 2024 @11:02AM (#40767967)
In a way, TCP is just about as reliable as UDP, but at a different layer: TCP will either forward your entire stream of data in order and without gaps, or it won’t. UDP does the same, but on the per-datagram level.

Reliability is arguably more of a statement about the availability metrics of your underlying network; it doesn’t seem like a great summary for what TCP does. You can’t make an unreliable lower layer reliable with any protocol magic on top; you can just bundle the unreliability differently (e.g. by trading off an unreliability in delivery for an unreliability in timing).

Re:Never* Use Datagrams by markhahn on Monday June 24, 2024 @03:03PM (#40779530)
As another reply points out, it has a useful and well-formed meaning, even if you don't like it.

UDP is at-most-once; TCP is exactly-once-in-order.

Re:Never* Use Datagrams by kevincox on Monday June 24, 2024 @03:24PM (#40779685)
There is minimal effort. If the queue has room the packet gets forwarded. If the situation is any more difficult than that the effort ends and the packet is dropped.
Re:Never* Use Datagrams by IshKebab on Sunday June 23, 2024 @07:53AM (#40766746)
> but the datagrams may be dropped anyway

That's what I thought "unreliable" meant? I can't really tell what misconception you are trying to avoid.

Re:Never* Use Datagrams by kbolino on Sunday June 23, 2024 @09:49AM (#40767456)
I think the issue is that there's a stigma around UDP, largely borne from not using it effectively. I'm not sure this is the right way to address the stigma though.

Ultimately, TCP vs UDP per se is rarely the right question to ask. But that is often the only configuration knob available, or at least the only way to get away from TCP-based protocols and their overhead is to switch over to raw UDP as though it were an application protocol unto itself.

Such naive use of UDP contributes to the stigma. If you send a piece of data only once, there's a nontrivial chance it won't get to its destination. If you never do any verification that the other side is available, misconfiguration or infrastructure changes can lead to all your packets going to ground and the sender being completely unaware. I've seen this happen many times and of course the only solution (considered or even available in a pinch) is to ditch UDP and use TCP because at least the latter "works". You can say "well it's UDP, what did you expect?" but unfortunately while that may have been meant to spur some deeper thought, it often just leads to the person who hears it writing off UDP entirely.

Robust protocol design takes time and effort regardless of transport protocol chosen, but a lot of developers give it short shrift. Lacking care or deeper understanding, they blame UDP and eschew its use even when somebody comes along who does know how to use it effectively.

Re:Never* Use Datagrams by IshKebab on Sunday June 23, 2024 @11:43AM (#40768262)
What kind of stigma is there around UDP? I have never heard of this and I have never seen anyone use UDP expecting it to be reliable.

I think the biggest mistake people make with UDP protocols is allowing traffic amplification attacks.

Re:Never* Use Datagrams by kbolino on Sunday June 23, 2024 @10:41PM (#40772305)
I don't think anyone expects it to be reliable, they just don't plan for packet loss properly.
Re:Never* Use Datagrams by lazide on Monday June 24, 2024 @01:02AM (#40772765)
Plan? Or implement?
Re:Never* Use Datagrams by kbolino on Monday June 24, 2024 @01:44PM (#40778777)
Both? I've seen UDP and TCP treated as interchangeable. They're not, even though in many cases the APIs involved make it seem that way. Choosing datagrams and unreliable transport vs. streams and reliable transport affects the rest of the protocol design and behavior, whether the designer wants it to or not and whether the implementer considered the consequences or not.
Re:Never* Use Datagrams by coldtea on Sunday June 23, 2024 @08:48AM (#40767092)
This sounds like the problem is the term "best-effort" (hand wavy, what's the measure of effort? What's "the best" effort?).

In the end, best-effort is just saying "unreliable" in a fussier way.

>But it does not make UDP inherently unreliable.

Isn't that exactly what it does make it?

If that's not it, then what woud an actual "inherently unreliable" design for such a protocol be? Calling an RNG to randomly decide whether to send the next packet?

Re:Never* Use Datagrams by vince14 on Sunday June 23, 2024 @09:22AM (#40767301)
Fire-and-forget?
Re:Never* Use Datagrams by justin66 on Sunday June 23, 2024 @11:09AM (#40768024)
There’s nothing intuitive about what “best effort” means, but if you know anything about udp and tcp you know which is “reliable.”

> UDP makes its best effort

TCP tries really hard, too, you know.

Re:Never* Use Datagrams by harrison_clarke on Monday June 24, 2024 @03:02PM (#40779513)
i agree that "unreliable" isn't a good term for the transport. reliability is a property of the system, not of the transport. and you can make an unreliable system with TCP or a reliable one with UDP

but, "best-effort" implies that it's doing some effort to ensure delivery, when it's really dropping any packet that looks funny or is unlucky enough to hit a full buffer

i like "lossy", but this is definitely one of the two hard problems