News for hackers. Stuff that matters.
Re:Never* Use Datagrams by dale_glass on Sunday June 23, 2024 @07:26AM (#40766615)
IMO one of the worst mistakes made in IP development was not having made a standard protocol for the one thing that pretty much everyone seems to want:

A reliable, unlimited-length, message-based protocol.

With TCP there's a million users that throw out the stream aspect and implement messages on top of it. And with UDP people implement reliability and the ability to transmit >1 MTU.

So much time wasted reinventing the wheel.

Re:Never* Use Datagrams by jzwinck on Sunday June 23, 2024 @08:04AM (#40766804)
Here is a good message framing protocol built on TCP: https://www.nasdaq.com/docs/SoupBinTCP%204.0.pdf

If you want large messages just redefine the length from 16 to 32 bits.

It's been used for millions of messages per day for 25 years and hasn't been changed in a long time.

Admittedly it isn't as common as TCP and that's a shame. But it's out there, it's public, it's minimal and it makes sense.

Re:Never* Use Datagrams by eru on Sunday June 23, 2024 @08:33AM (#40766984)
> SoupBinTCP guarantees that the client receives each sequenced message generated by the server in the correct order, [...]

This protocol guarantees too much. It's still a stream.

Re:Never* Use Datagrams by jzwinck on Sunday June 23, 2024 @09:38AM (#40767391)
You quoted the part about sequenced messages. Look at the part about unsequenced messages right after that. It has both.
Re:Never* Use Datagrams by eru on Monday June 24, 2024 @01:40AM (#40772891)
Thanks!
Re:Never* Use Datagrams by H8crilA on Sunday June 23, 2024 @07:44AM (#40766703)
Sorry for a useless comment but now I feel so stupid for never noticing that pretty much everything done on TCP is actually message exchange, not streams. The mismatch is indeed so unfortunate.
Re:Never* Use Datagrams by eru on Sunday June 23, 2024 @08:32AM (#40766981)
Well, you often have some dependency between messages. Some re-orderings don't matter, but some do.

If you just keep everything in the same order, then you never have to worry about any re-ordering.

I can see why people picked streams as the one-size-fits-all-(but-badly) abstraction.

Re:Never* Use Datagrams by tliltocatl on Sunday June 23, 2024 @09:10AM (#40767225)
Because worse is better and if you try to be everything you (don't) get OSI. Also because everyone loves serial ports and dialup modems and TCP just emulates a serial port over packet network. And it wasn't supposed to be one-size-fits-all, rather «let us have telnet while we figuring out the rest» but then ossification happend.
Re:Never* Use Datagrams by iainmerrick on Sunday June 23, 2024 @08:45AM (#40767067)
Is it really that unfortunate? What’s the big downside?

There’s a bit of reinvention needed, sure, but adding a framing layer is about the easiest task in networking. If you want a standard way of doing it, these days you can use a WebSocket.

Edit to add: oh, I see, you want reliable but unordered messages. That would definitely be useful sometimes, but other times you do want ordering. If you don’t need ordering, isn’t that pretty much what QUIC does?

Re:Never* Use Datagrams by p_l on Sunday June 23, 2024 @08:51AM (#40767112)
SCTP did both reliable/unreliable and ordered/unordered, with QUIC arguably being at least a bit inspired by it, but going over UDP because internet is broken.

EDIT: Internet being broken is also why there's a grease extension for QUIC

Re:Never* Use Datagrams by taneq on Sunday June 23, 2024 @09:55AM (#40767493)
What would ‘reliable but unordered’ even mean? What’s the difference between a dropped message and one that’s just late?
Re:Never* Use Datagrams by saurik on Sunday June 23, 2024 @10:05AM (#40767550)
The difference is whether you get to process the ones which came after first or you must wait for the retransmission of the earlier ones. FWIW, SCTP provides for this difference.
Re:Never* Use Datagrams by Aurornis on Sunday June 23, 2024 @10:31AM (#40767722)
> I feel so stupid for never noticing that pretty much everything done on TCP is actually message exchange, not streams.

This generalization isn’t true at all. Streaming data over TCP is extremely common in many applications.

When you download a large file, you’re streaming it to disk, for example.

I guess you could get pedantic and argue that an entire stream of something is actually one large message, but that’s really straining the definitions.

Re:Never* Use Datagrams by adrian_b on Monday June 24, 2024 @01:22PM (#40778585)
By numbers of communication actions, pretty much everything may actually be a message exchange, but by the amount of data that was transferred for many years the file downloads and uploads had been dominant on the Internet, which are the kind of thing for which TCP has been designed. For a big file more data may be transferred than for thousands or millions of message exchanges.

Nowadays perhaps video streaming, which may be lossy, so TCP is not needed for it (i.e. what is now called streaming does not have the reliability requirements of the TCP streams), might transfer more data on the Internet than file downloads, but that is not a desirable technical evolution, the replacement of downloading with streaming is just a means to extract more money from those who are satisfied by such a service.

Re:Never* Use Datagrams by ajb on Sunday June 23, 2024 @08:07AM (#40766826)
Actually, the mistake in IP was in not encrypting the next layer, so that networks can block transport protocol innovation by filtering anything other than TCP and UDP. This is the mistake that quic has fixed.
Re:Never* Use Datagrams by Ekaros on Sunday June 23, 2024 @08:29AM (#40766958)
I think that one can be forgiven for pure lack of processing power... We forget just how under powered even host machines were and how resource hungry encryption is...
Re:Never* Use Datagrams by d-z-m on Sunday June 23, 2024 @08:49AM (#40767098)
QUIC still runs over UDP. Are you referring to MASQUE?
Re:Never* Use Datagrams by ajb on Sunday June 23, 2024 @09:08AM (#40767211)
I should perhaps have said "works round" rather than fixes - yes, it has to run over UDP but the quic team had an explicit goal of not allowing the network to interfere further : see sec 3.3 and 7.5 of https://dl.acm.org/doi/pdf/10.1145/3098822.3098842

This now means that innovations based on Quic can occur

Re:Never* Use Datagrams by mycall on Sunday June 23, 2024 @10:15AM (#40767634)
Since both QUIC and UDP are transport layers, does this mean that once switches and ISPs start supporting QUIC along side UDP and TCP, that a new version of QUIC can be released which doesn't require UDP?
Re:Never* Use Datagrams by ajb on Sunday June 23, 2024 @02:25PM (#40769446)
Switches don't need to change anything to support QUIC, precisely because it uses UDP. So, the deployment of QUIC doesn't involve any technical changes that would enable a version of QUIC that worked directly over IP. It's possible that the defeat of middleboxes would change the motivation of ISPs to filter out alternate protocol numbers, meaning that there might be less resistance to getting them to allow that in the future - but doing so is still a big exercise.

Also, the overhead of a UDP packet is 8 bytes total, in 4 16-bit fields:

- source port

- dest port

- length

- checksum

So, we can save a max of 8 bytes per packet - how many of these can we practically save? The initial connection requires source and dest ports, but also sets up other connection IDs so theoretically you could save them on subsequent packets (but that's pure speculation, with zero due diligence on my part). It would require operational changes and would make any NATs tricky (so practically only for IPv6) Length and checksum maybe you can save - QUIC has multiple frames per UDP datagram so there must be another length field there (anyway, IETF is busily inventing a UDP options format on the basis that the UDP length field is redundant to packet length, so can be used to point at an options trailer). QUIC has integrity protection but it doesn't seem to apply to all packet types - however I guess a checksum could be retained for those that don't only.

So in sum maybe you could save up to 8 bytes per packet, but it would still be a lot of work to do so (removing port numbers especially)

Re:Never* Use Datagrams by DoneWithAllThat on Sunday June 23, 2024 @09:16AM (#40767265)
This was absolutely not feasible at the time IP was being developed. There simply wasn’t enough computational power available or good encryption algorithms invented yet. And you can make a reasonable argument that that’s not the responsibility of that layer of the stack.
Re:Never* Use Datagrams by LtWorf on Sunday June 23, 2024 @09:49AM (#40767460)
Encryption without authentication is rather useless. Just slows things down for no advantage.
Re:Never* Use Datagrams by Ekaros on Sunday June 23, 2024 @07:55AM (#40766751)
Now I wonder. Do we have any actual streaming use of TCP, with purely streaming protocol.
Re:Never* Use Datagrams by eru on Sunday June 23, 2024 @08:35AM (#40767002)
Yes. When your messages need to be received and processed in the same order they are sent, then a stream is a good (or good enough) abstraction.

For most applications some re-orderings of messages don't matter, and others would need special handling. So as a one-size-fits-all-(but-badly) abstraction you can use a stream.

> Do we have any actual streaming use of TCP, with purely streaming protocol.

But to give you a proper answer: the stream of keyboard inputs from the user to the server in Telnet (or SSH).

Re:Never* Use Datagrams by Ekaros on Sunday June 23, 2024 @08:45AM (#40767065)
Opens up the question that if you have "messages" are you a stream anymore? Can your stream of messages start mid message for example? Surely a stream can have this happen. Or are you instead messages send over a stream. In which case abstraction of stream instead of reliable message transportation is bit weird.

Wouldn't each input be a single albeit too short message? But this level of granularity really makes little sense...

Re:Never* Use Datagrams by eru on Monday June 24, 2024 @01:40AM (#40772889)
If you have a reliable-byte-stream abstraction, you only need to add a way to serialise your messages into bytes, and you get a reliable-messages-in-order abstraction for 'free'. That's convenient! And you don't need to teach your lower level protocols about where your higher level messages start and end.

You can also stick your higher level messages into a structure that's more complicated than a stream, eg you can stick them into a tree. Anything you can serialise, you can send.

Of course, the downside to this is that when you don't need these strong guarantees, you are paying for stuff you don't need.

Re:Never* Use Datagrams by nyc_pizzadev on Sunday June 23, 2024 @10:26AM (#40767693)
High quality VOD (ie streaming a 4K movie). HTTP block file systems, each block needs to be streamed reliably to fulfill the read() call plus read ahead.
Re:Never* Use Datagrams by Ekaros on Sunday June 23, 2024 @10:46AM (#40767816)
For VOD can I just open connection and send single message and then stream will continue forever? And HTTP is message oriented protocol. I can't just send infinite length HTTP message. Which would be processed as it arrives or can I? Meaning can I upload something not that small like terabyte of video data over HTTP?
Re:Never* Use Datagrams by nyc_pizzadev on Sunday June 23, 2024 @02:45PM (#40769604)
Yes for everything. In HTTP1 it’s a chunked response, in H2+ it’s just a bunch of data frames. This is how low latency HLS video works.
Re:Never* Use Datagrams by hansvm on Sunday June 23, 2024 @11:13AM (#40768050)
Think about what the feature (potentially) buys you:

(1) zero-copy, zero-allocation request processing

(2) up to a 2x latency reduction by intermingling networking and actual work

(3) more cache friendliness

(4) better performance characteristics on composition (multiple stages which all have to batch their requests and responses will balloon perceived latency)

If you have a simple system (only a few layers of networking), low QPS (under a million), small requests (average under 1KB, max under 1MB), and reasonable latency requirements (no human user can tell a microsecond from a millisecond), just batch everything and be done with it. It's not worth the engineering costs to do anything fancy when a mid-tier laptop can run your service with the dumb implementation.

As soon as those features start to matter, streaming starts to make more sense. I normally see it being used for cost reasons in very popular services, when every latency improvement matters for a given application, when you don't have room to buffer the whole request, or to create very complicated networked systems.

Re:Never* Use Datagrams by tliltocatl on Sunday June 23, 2024 @07:52AM (#40766739)
You are looking for SCTP.
Re:Never* Use Datagrams by lxgr on Sunday June 23, 2024 @09:47AM (#40767444)
Which you will absolutely not get past pretty much any middleboxes, unless you encapsulate it in UDP.
Re:Never* Use Datagrams by kixelated on Monday June 24, 2024 @02:04PM (#40778988)
I tried using SCTP before QUIC. Unfortunately, while the API looks like you can mix reliable/unreliable messages, in reality the transport doesn't support it because of how FORWARD-TSN works. There were some other pretty fundamental blockers too.
Re:Never* Use Datagrams by supriyo-biswas on Sunday June 23, 2024 @07:43AM (#40766698)
Re:Never* Use Datagrams by jan_k_ on Sunday June 23, 2024 @08:27AM (#40766939)
WebSocket?
Re:Never* Use Datagrams by paulgb on Sunday June 23, 2024 @09:01AM (#40767168)
WebSocket is over TCP, so still ordered. I think by message-based GP is talking not only about message framing (which WebSocket provides) but also reliable out-of-order delivery.
Re:Never* Use Datagrams by ori_b on Sunday June 23, 2024 @09:45AM (#40767429)
When does a long out of order delay look like a packet loss?

Is it possible for an out of order packet to get delayed by a millisecond? A second? A minute? An hour?

Have you written code to be robust to this?

Re:Never* Use Datagrams by paulgb on Sunday June 23, 2024 @11:05AM (#40767985)
Other people have probably thought about it more than I have, but the way I see it working is that a set of unacked messages are stored on each end of the connection. When a connection receives a message, it acks it by ID. When acks come out of the order the client sent them in (or after a timeout period), it re-sends the packet that may have dropped.

If every message is getting dropped, the set of unacked messages fills up and the connection stops accepting messages from the application, similar to TCP in that situation.

I mostly work with TCP so haven't had to deal with unreliable channels generally, but I do use a similar approach at the application level for reliable delivery across reconnects.

Re:Never* Use Datagrams by ori_b on Sunday June 23, 2024 @02:09PM (#40769345)
My point is that a lost message looks the same as an arbitrary delay.
Re:Never* Use Datagrams by p_l on Sunday June 23, 2024 @08:50AM (#40767103)
That's because TCP evolved as, essentially, abstraction of serial port.

And due to various political & cultural & industrial lobbying, more flexible but complex on their face approaches (OSI) were rejected.

TCP meant you could easily attach a serial terminal to a stream, a text protocol meant you could interact or debug a protocol by throwing together a sandwich, an undergrad, and a serial terminal (coffee too if they do a good job). You could also in theory use something like SMTP from a terminal attached over a TIP (which provided dial-in connection into ARPAnet where you told the TIP what host and what port you wanted).

If you look through some of the old protocol definitions you'll note that a bunch of them actually refer to simplest mode of TELNET as base.

Then in extension of arguably the same behaviour that blocked GOSIP mandate we have pretty much reduced internet to TCP, UDP, and bits of ICMP, because you can't depend on plain IP connectivity in a world of NAT and broken middleboxes.

Re:Never* Use Datagrams by throwaway7ahgb on Sunday June 23, 2024 @09:15AM (#40767256)
Correct on the reliable UDP.

I've seen a few implementations of a reliable UDP messaging stream (using multicast or broadcast). It uses a sequencer to ensure all clients receive the correct message and order.

It can be extremely fast and reliable.

Re:Never* Use Datagrams by taneq on Sunday June 23, 2024 @10:05AM (#40767555)
If it guarantees delivery and preserves order, what’s the difference vs. TCP?
Re:Never* Use Datagrams by colanderman on Sunday June 23, 2024 @10:21AM (#40767672)
Delimited messages vs. stream.
Re:Never* Use Datagrams by throwaway7ahgb on Monday June 24, 2024 @08:49AM (#40775381)
Much much faster, TCP is very slow and complicated (relatively). This can be sped up by not using the kernel using something talking directly to hardware.
Re:Never* Use Datagrams by FpUser on Sunday June 23, 2024 @09:34AM (#40767368)
I have implemented publish/subscribe middleware in the 90s using UDP and reliable IP multicast. It was not too hard to do and had taken me about two month. Yes I did reinvent the wheel but it had numerous positive sides:

  a) It added yet another area of expertise to my portfolio.
  b) I did it because it was needed to facilitate another product in the company where I worked. The alternative at the time would be paying $350,000 for middleware from Vendor-X. Not acceptable.
  c) Vendor-X people noticed us, loved what we did and made us a partner to resell their middleware and we've made a ton of money on deployment, configuring and consulting services.
Re:Never* Use Datagrams by _zoltan_ on Sunday June 23, 2024 @10:29AM (#40767716)
libfabric implements msg on top of TCP, among others. I love that I can just switch between TCP and RDMA without any code change.
Re:Never* Use Datagrams by bvrmn on Monday June 24, 2024 @03:16AM (#40773282)
> unlimited-length

Where to keep in-progress frame data? I case of TCP it's an app and buffer for only a single frame or app even could make "stream processing" for in-progress frame.