92 comments

[ 2.8 ms ] story [ 159 ms ] thread
I've been dying to write a protocol to replace both TCP and UDP (me being naive, I think I could write a decent one). I feel like there's fundamentally really no good reason to have multiple protocols, because fundamentally, neither is UDP 100% unreliable, nor is TCP 100% reliable. I think what we should really have is just one protocol with adjustable tolerance parameters. But I haven't had the time to put much thought into stuff like congestion control, so I don't know what it involves yet. I'm glad someone is doing something similar though.
UDP and TCP do not differ just because of reliability, they also differ because TCP is a stream protocol and UDP is not.

By not being designed to handle streams, UDP can sidestep a ton of issues.

So, the adjustable parameters in your protocol should be a lot, methinks.

I see why it appears that way, but I wasn't trying to suggest that reliability was the only distinction. However, I'm not sure I see such a fundamental distinction between the two that requires these to be two separate protocols. I can imagine parameters like "max wait time allowed before packet is skipped", "max contiguous packets allowed to be skipped", "whether to deliver packets that arrive out of order", stuff like that. Because ultimately TCP is at the extreme of retrying forever until every byte is received in order (or, well, until a timeout happens and we give up), and UDP is at the extreme of not retrying at all. It shouldn't be that bad to interpolate between the two I think?
The tunability aspect of your idea scares me a little. When you choose TCP or UDP, you are making some guarantees about how the connection is going to behave.

My fear here is that you lose those guarantees once you allow configuration of the connection using your one protocol. ...And while sure, you can have that negotiated when the connection is set up, there would be nothing from preventing one side of the connection from fudging/cheating/outright lying. I wouldn't put that past people at all -- especially networking hardware vendors.

Any attempt you would implement to mitigate this just adds unnecessary data transmission overhead.

> When you choose TCP or UDP, you are making some guarantees about how the connection is going to behave.

Huh? With UDP, the thing missing is a guarantee about how the connection is going to behave (assuming you call it a "connection" in the first place). I'm just talking about interpolating between guarantees and no guarantees.

> With UDP, the thing missing is a guarantee

Not so - with UDP I know that the endpoint won't discard packets that arrive out of order, and won't bother me with retrans requests for stale packets that didn't arrive... different priorities, different kinds of 'guarantees'

You can configure retries in TCP. There's a ton of differences in how they're implemented underneath, merging them might be possible but you would probably end up with something that was worse for streams than TCP and worse for datagrams than UDP even if it could do both.

There's three different retry strategies in TCP I know of. Like 7 or 8 popular congestion control algorithms, many types of queuing disciplines.

Some fundamental differences like the SYN/ACK handshake, SYN cookies, state table conntrack, packet sequencing stuff. Tcp slow start and windows. Tons of optional features.

The TCP stack of any newer OS is monstrous. A lot of kernel devs would cringe at the thought of adding more to that :)

> You can configure retries in TCP. There's a ton of differences in how they're implemented underneath, merging them might be possible but you would probably end up with something that was worse for streams than TCP and worse for datagrams than UDP even if it could do both.

I don't think that's the same kind of retry as the one I'm talking about. In TCP, no matter what the retry algorithm is, TCP has to deliver data in order. Whereas I'm talking about being able to tune how much you're willing to retry receiving the data until you give up and return it to the caller out of order. It's not about the algorithm so much as the resulting semantics.

(comment deleted)
SCTP allows configurable delivery parameters - you can choose whether data should be reliable, how many retransmissions, whether it needs to be in order, etc.

It's used for WebRTC data channels:

https://www.html5rocks.com/en/tutorials/webrtc/datachannels/

Also worth checking out enet:

http://enet.bespin.org/Features.html

Thanks, I'll take a look. From your description and my previous thoughts about the problem, the problem I see is that is "whether data should be reliable" and "how many transmissions" are not the sorts of parameters you want. Nobody cares about the number of retransmissions; people care about how much time is spent transmitting. And no connection is ever 100% reliable, so you want more than a Boolean.
If you allow tcp to drop/re-order packets, the entire abstraction of a stream protocol is gone. The application now has to understand packet boundaries, which packets are missing, etc.

So to me it sounds like you just want to write a UDP protocol with some extra reliability. Most applications built on top of UDP do this already, but maybe there would be some value in a general library for UDP protocols.

> If you allow tcp to drop/re-order packets, the entire abstraction of a stream protocol is gone. The application now has to understand packet boundaries, which packets are missing, etc.

I don't think so. On the receiver's side, the application doesn't need to know packets at all -- it just deals with a stream of bytes where some portions may be dropped or come out of order. The packet nature would be abstracted away. On the sender's side, packets only become relevant if the application wants to get optimal behavior with respect to the packet size (in which case it would be already doing its own manual UDP). If it just wants "good enough" generic behavior (which is what TCP has always been providing for everyone) then it can again ignore the packet nature and just treat the connection as a stream where some portions may be dropped and/or reordered.

Think about how useful this could be in so many common situations: when you're trying to download some file, for example, you don't need TCP -- because it doesn't matter if the data comes out of order. You just need to make sure you get everything eventually and that the data isn't corrupted. You don't want UDP either, which would require you to implement your own feedback/congestion control/etc. mechanisms from scratch. There's a nice sweet spot in the middle waiting to be hit. And it baffles me that it still doesn't seem to have been done.

The receiver now has to figure out what is missing from a stream of data of which anything could be missing. That's equivalent to dealing with missing packets only on a byte level. If anything, that's harder and less efficient to deal with.
Eh, I'm not too optimistic about this. Too many millions of routers and middleboxes only support TCP and UDP for this to ever be workable on the public internet. Since layer 4 is traditionally done in the kernel were talking about updating the firmware of countless devices. A better solution is to piggyback on UDP support and add your own protocol in user space.

building a protocol on top of UDP has historically been a good compromise. The base protocol is simple enough that it doesn't add much overhead to just build whatever you want on top of it. The ubiquitous support for UDP leaves little reason to roll your own.

The only bad downside to both UDP and TCP is that support for unsolicited connections is usually completely broken for end users since the 90s because of the vast adoption of NAT.

> A better solution is to piggyback on UDP support and add your own protocol in user space.

I haven't looked at the code, but I imagine this would be relatively trivial to change if it is written at all sanely, right? Hardly sounds like a big thing to focus on.

It's just semi pointless to try to use anything but UDP and TCP on the www. If you need to encapsulate the MTU path discovery n stuff doesn't work and you're better off just using existing protocols that build on UDP.

Look at all the foot dragging with IPV6, and that's just an updated version of an existing protocol with massive support behind it

I know it's nitpicky but www != the internet.
The code in the article doesn't implement DCCP. It simply requests that the OS create DCCP sockets to use for their client-server example:

int listen_sock = socket(AF_INET, SOCK_DCCP, IPPROTO_DCCP);

If the OS doesn't support DCCP, then, tough luck...

... can always use raw sockets, with the correct set of root-ish privileges or capabilities.
Sure, crafting packets with compliant DCCP headers is simple enough. But, implementing congestion control, which is the raison d'être of DCCP is decidedly a non-trivial undertaking.
This is already being talked at higher levels than layer 4 though, notably by LEDBAT but I'm sure there's others
The problem isn't necessarily that the change would be hard, it's that getting everyone to update would be nigh-impossible.
Well technically the only thing those routers and middleboxes need to support is IP, why some of them decide they need to meddle with the payload is something I don't understand.
> Well technically the only thing those routers and middleboxes need to support is IP

If they are doing NAT, they need to understand the transport layer protocol too.

>If they are doing NAT, they need to understand the transport layer protocol too.

And this is why we need IPv6.

With ipv6 they still need to understand protocols to do connection tracking.
Routers that don't do NAT don't need to do connection tracking.

Firewalls do, but it's possible to put the firewall in the endpoint.

Why is connection tracking necessary?
Luckily, no three letter agency will abuse this to track anyone if we use IPv6 completely unNATted as it was intended to be used.

/s

There are ways to fix that.

One of the interesting ones is to have every socket call to bind() without an explicit address allocate a random new IPv6 address. Then there is nothing to correlate the address with because every other socket on that machine has a different address.

It is indeed interesting, and useful from an privacy perspective (in the sense that it masks the correlation between different connections from the same machine).

You do need to define some "trustworthy" machines which get to see a constant (and known) address - or troubleshooting and debugging the network will be horrible. Also, I suspect some protocols (pop-before-smtp, stun) won't like it. They are unneeded in IPv6, but I suspect there exist ones that will fail horribly with this scheme.

> You do need to define some "trustworthy" machines which get to see a constant (and known) address - or troubleshooting and debugging the network will be horrible.

In enterprise environments you could get the addresses from a DHCPv6 server which would then be able to map them back to machines. Or register them in the internal reverse DNS.

> Also, I suspect some protocols (pop-before-smtp, stun) won't like it. They are unneeded in IPv6, but I suspect there exist ones that will fail horribly with this scheme.

It would be less trouble to make addresses per-process rather than per-socket, but also somewhat less effective. A good middle ground might be to default to per-process and have a socket option to make it per-socket. That way e.g. Firefox could still have different addresses for connections to different servers.

A process could then choose which sockets use the same address as one another by calling getsockname() on an existing socket and then using that address to bind() another one.

Network operators often exploit router configurations to do custom routing or even poor man firewall configurations that work off data in the TCP packets. The device manufacturers love this because it allows for vendor lock-in.

I agree with you; though, I do wonder what will start happening at the routingnlayer of the internet to start dealing with these massive DDOS attacks that have been going on.

I've been reading a lot into these recent DDoS attacks and countermeasures. Even though syn cookies are a hack they fix the biggest exploitable resource hole in TCP. It's now possible to initialize TCP using no stored state info but hardly anyone is doing it in practice.

The biggest reason is that traditional NAT requires a separate conntrack state table. The big players (looking at you google, cloudflare) have solved this by using consistent hashing to load balance traffic but they're not sharing the code.

Google made a show of good faith recently by releasing a comprehensive paper on how their load balancer works, hoping the open source movement will pull a mapreduce/hbase and built a replica off of it but this far it isn't happening.

I think google gave up considering that they've seen how much money cloudflare makes selling the software as a service and now offer their own servers as DDoS protection.

I've been looking deeply into the matter. The truth is that open load balancers relying on the kernel are not going to work. Someone needs to get started on this, and I've considered doing so myself but it's a big undertaking for a single dev

Thanks for the reference on Google's load balancing. Is this the Maglev load balancer paper [1] available on Google Research?

[1] https://static.googleusercontent.com/media/research.google.c...

Yup that's it. Me and other kernel devs have been toying with the idea for years, but google actually went out and did it, and documented it. They proved it was possible.

It's something that absolutely should be picked up and run with

> Well technically the only thing those routers and middleboxes need to support is IP

Generally speaking, security devices need to support a lot more than just raw IP to do their jobs these days. At this point the installed base of firewalls alone would make implementing a new protocol like this across the internet effectively impossible.

Add in devices that do NAT, ALGs, load balancers, and other intelligent network devices and you can see why everyone that needs something like this on a real network uses UDP with stuff built on top.

Had the OSI network model won out eons ago we would have enough separation between layers to use custom protocols. For better or worse, that battle was long decided by TCP/IP and the two have been tightly intertwined ever since.

It's too bad but at the same time running custom protocols on UDP really isn't too bad as far as CPU/Space overhead. It's pretty much become a universal encapsulation protocol for everything else

intelligent network devices

That's why those should get scrapped and replaced by dumb pipes. They only cause pain. I thought this lesson had been learned decades ago already.

(comment deleted)
Isn't DCCP just an congestion control add-on that is generic, and you can for example use it over UDP? In that case it wouldn't matter, as long as routers support UDP, which they do.
SCTP and QUIC should get some mention here too.
There's also SCTP:

Stream Control Transmission Protocol (SCTP) is a transport-layer protocol, serving in a similar role to the popular protocols TCP and UDP. It is standardized by IETF in RFC 4960.

SCTP provides some of the same service features of both: it is message-oriented like UDP and ensures reliable, in-sequence transport of messages with congestion control like TCP; it differs from these in providing multi-homing and redundant paths to increase resilience and reliability.

https://en.m.wikipedia.org/wiki/Stream_Control_Transmission_...

Edit: fix typo

It's also (usually) routed over the Internet properly in my experience.
SCTP may see more usage in the wild because of WebRTC.
WebRTC does not use real SCTP but a rather a tunnel over UDP. Besides, it's not like WebRTC accounts for a significant amount of Internet traffic. I'd say SCTP sees more usage simply because it has been around for much longer with SS7 being the primary use case.
There is a standards track RFC that defines SCTP over UDP. RFC 6951 "UDP Encapsulation of Stream Control Transmission Protocol (SCTP) Packets for End-Host to End-Host Communication".
Sure. But it's still not real SCTP if the IP header's Protocol field doesn't say 0x84 :D
Also QUIC, which got most of its ideas from SCTP and some from DCCP.
SCTP really really deserved to be widely deployed.
HTTP should have made SCTP a lot more popular. SCTP is a natural fit for reliably transporting static files, which is what HTTP was originally designed for. So many of the HTTP2/SPDY/etc. features are there to make up for the fact that TCP doesn't have a length "field" since it's stream-oriented.

Obviously, there are exceptions and you can have both streams and known-length content served over HTTP, but I still think streams over SCTP would have been a better choice than datagrams over TCP.

Edit: Also firewalls that filter out anything but TCP (or TCP + UDP, or TCP + UDP + ICMP) can die a fiery death. The fact that basically any new protocol has to tunnel over UDP instead of properly over IP is heresy and bullshit.

Considering the MTU issues: Does anyone know why this was not solved in IP (and IPv6) by the following method:

1) There is a field MTU in the IP header.

2) The sending host sets MTU := <MTU of the outgoing link>.

3) Any router on the path sets MTU := min(MTU, <MTU of outgoing link>).

4) The receiving host instantly knows the MTU of the path (the MTU field).

This seems like a much simpler, more reliable and more efficient system than PMTU discovery: no problems with firewalls blocking ICMP, no additional delay due to too large packets.

All at the cost of a single minimization operation at the router. The IP header checksum would need to be recalculated, but, due to the simplicity of the IP checksum, fixing it up changing one word is trivial (AFAIK).

I can imagine a potential issue with adding that to IPv6 when it was designed, that IPv6 should be tunnelable over IPv4 which doesn't have this, but still surely there are ways to deal with that.

A path may not be symmetric.
Good observation. But it's not a deal-breaker. The receiving host can report that MTU back to the sender (to which it would really apply in case of asymmetric paths), e.g. as part of the TCP handshake in a TCP option, and possibly subsequently if it changes.

I'm sure there are details that would have to be ironed out. Like what happens if the MTU of the path is then reduced (does this result in dropped packets and leads to a stall? - possible fix is to say the packets are truncated instead allowing the MTU to be propagated).

IP is stateless. Paths are changing. First packet has to be able to reach its final destination. Overall, the solution seems to quickly become complicated and routers need to modify headers and recompute checksums, something that was removed from IPv6.
Yes. If the path changes to one with a lower MTU, there might be a problem. Could be solved by truncating the packet instead of dropping it. Actually, I think this would be an even better approach. No extra field in the IP header, just truncation of packets that are too large, without changing the packet length field in the IP header. Upon seeing a truncated packet, the receiver could inform the sender of the detected path MTU (the length of the received packet).

EDIT: Well, if the MTU in the other direction also decreased, we might have an issue, as the stack might decline to interpret the transport layer payload. Don't know how to solve that right now, but probably there are ways. Maybe some mechanism to allow the protocol layer (TCP) to still successfully validate the TCP checksum knowing that the packet was truncated.

You're receiving lots of criticism from people that (correctly) see issues with your proposal. I just wanted to say that I like your thinking. Rather than going "doesn't work because scenario x" you work the problem and try to find something that does work. It sounds like a good idea, an MTU header in IP. The header can be extended if I remember correctly, so it might even be feasible to implement with backwards compatibility (avoiding another v6 to v7 transition).

I don't know how v6 was designed exactly, but if it's open, did you search back to see if someone proposed this and why it was rejected (if ever proposed)?

IP is based on packet switching and has no concept of a circuit/connection. Each subsequent packet sent between same endpoint can take different path with different PMTU.

Also, dedicating even two bytes in each and every IP packet just for MTU would be quite an overhead, especially since IP already has a mechanism (fragmentation) to deal with this.

> no concept of a circuit/connection

This is true but I don't see how that is relevant here. My proposal does not change this. It's just about a field in the header and logic required at routers for updating it.

> Each subsequent packet sent between same endpoint can take different path with different PMTU.

That is true for the existing Internet as is, and is also an issue for PMTU discovery. It's not a new issue caused by this proposed design. It can be addressed in the similar way as it is now (I don't know exactly how it is...).

I don't buy the "quite an overhead" argument - it wasn't a problem to extend the IP header from 20 to 40 bytes going from IPv4 to IPv6. For this you'd need just 2 bytes.

There may also be a different but similar approach: have routers truncate (not drop) too large packets but leave the "packet length" field intact. Upon seeign a truncated packet the receiver would know that the packet is too large, and what the path MTU is (the size of the packet).

If there is no circuit concept in the IPv4 and IPv6, then the value of the field could (in principle) vary wildly from packet to packet. In real life condition it most likely wouldn't - and even if it would, maybe that would be actually better than transparently fragmenting packets just because MTU changed after higher level connection has been established.

IPv6 packet header is significantly simplified when compared to IPv4. Although it is twice as large, almost all non-essential fields have been moved to extension headers. I guess it wouldn't hurt too much if there was an optional header with PMTU updated by all supporting routers along the path, especially when there is no checksum field in IPv6 packet.

> [better than] transparently fragmenting packets

In v6 there is no fragmentation anymore if I remember correctly, it would just get dropped (or maybe trigger an ICMP error, I don't know).

Additionally, this would tell the receiver the sender->receiver MTU, which doesn't do much good since the receiver->sender path may not be symmetric. You'd need four bytes, and 32 bits is a large chunk of the IP header.

You could use options, but you still have to deal with broken firewall hardware.

(comment deleted)
In reality the MTU is 1500 because the odds of all devices on a given path supporting anything larger is almost zero. The only way IPv6 could have helped was mandating a larger fixed known MTU... say 4096 or 8192.
> 1) There is a field MTU in the IP header.

You don't need this in every packet, you only need it in one packet (or once every few minutes). Instead of putting a field in every packet that only <1% of them need, we could create an out of band message to notify when the MTU has been exceeded. And the endpoint that needs to know that is the sender, so that's who you would send it to. Which is what they did.

That works perfectly well, the problem is that many misconfigured firewalls drop the ICMP messages. No one predicted that level of incompetence when the protocols were being designed.

QUIC has congestion control and is implemented on top of UDP, so it can go anywhere UDP does. https://www.chromium.org/quic
True, though QUIC is like TCP or SCTP in that its intended use is to transport streaming data rather than datagrams.
QUIC keeps message boundaries (just like SCTP) and also got congestion control negotiaton from DCCP.
Network equipment will most likely not support it. Same as SCTP, so it is only workable if you get custom firmware.
As another commenter mentions SCTP can be encapsulated if needed. SCTP is actually in pretty wide use in online gaming, and has been since at least 2007...
SCTP > DCCP
So... tell us more? This comment is about as useless by itself as "vim ftw" would be on an Emacs article.
And honestly, "DCCP vs SCTP" is more like "ed vs vim". They are both meant to address the needs of very different use cases.
I fully understand that networking protocols are truly in the center of the main vein of subjects interesting to the community of Hacker News. But can we at least admit to ourselves that being endlessly enamored with novelty and lack of precedence, telegraphs our deepest motivations to people who might have ulterior motives, allowing them to easily gain our attention and compliance by simply pointing out to us that the world is filled with irony, and novelty, and unprecedented phenomena?

If you remove "DCCP", "socket", and "type" from this headline, you are left with the universal format of a clickbait headline. If DCCP is truly a networking protocol worthy of the attention of the readers of Hacker News, just imagine how much more convincing of an argument there is to be made, based on its true underlying merits. I am perfectly willing to admit that this protocol may in fact be the best networking protocol by every objective measure available. But the fact that someone who knows more than I do about it, believes that their best opening bid in the negotiation that is convincing me of its merits, is a logical fallacy, inevitably leads me to question their entire premise.

If we can all agree that we don't like clickbait headlines in the general sense, then lets be even more vigilant against clickbait headlines that we are the least able to resist.

Edit: added a couple of missing words that were lost on the way from my brain to my fingers.

I think you're reading a little too much into it. The title, like the conclusion, was supposed to a joke about how DCCP is obscure and therefore hipster-esque. The intention of the article wasn't so much as to make the case for the merits of DCCP but to describe some of the aspects of networking technology that would be unfamiliar to most people, including the much of the Hacker News community. I really don't see how describing something as obscure is logically fallacious.

While I will admit that I did choose the title to be alluring, I do not think it is provocative, sensationalising or misleading in any way to be called clickbait.

The inherent nature of employing logical fallacies is that the employer is pointing to a correlation, in the hope that they can convince you of causation.

Causation is like a perfect happy path through a software application, whereas any single correlation is a singular path through the application. Out of all possible paths through a software application, vast amounts of those paths result in failure, whereas far fewer paths result in success. We can all agree that performing tests on the happy path is important, but inferior to 100% code coverage, if our eventual goal is to harden our software against failure, both malicious and accidental.

The point I'm driving at is not that we should all become perfectly logical at every moment of our life, because the logical, bitter end of that is a world of sociopaths, completely devoid of any humanity, emotion, love, and all of the other things we can all agree are just as important as logic and reason.

My point is that if we are in complete consensus about clickbait titles, with respect to subjects that we don't find interesting, yet are willing and able to defend clickbait titles when they happen to bait us in to clicking them, that is the perfect marriage of our ignorance and arrogance. If we can point out to less informed management that their desire to reduce friction along the happy path of software is _precisely_ what increases attack surfaces, why can't we see that same flaw in ourselves? The answer is not to rush to one extreme to prevent the other. The answer is to strike balance.

We've updated the submission title to a representative portion of the sub-title. Your explanation is appreciated and we're not trying to be draconian about this, but we nearly always update titles when there are clickbait elements (singularity: "The X that ...", addressing the reader: "you") and complaints in the thread.
Thank you. I can see now that my argument is largely equivalent to beating people over the head with logic, and simply shouting "logic!".

My central point is that clickbait titles beat people over the head with what they were already predisposed to hear, which is bad. But my continued explanation in and of itself is the same insidious tactic.

Thanks for your patience with me, and with all of us.

I will also give you the benefit of the doubt in this case. I guess I've been having some profound realizations as of late how the most important teenager in my life is utterly consumed by memes, and my fellow Americans are consumed by political news, and from where I stand, I am frustrated that what is so obvious to me is so difficult to explain to the entertained/frightened/insert emotional state here.

I don't mean to call you out as the most extreme example of my point, nor do I mean to show that this is the first time I am seeing this. But I see this optimization toward 8 lane highways we construct from content creators towards our brains, for the purposes of being entertained while exerting the least amount of effort necessary, as a giant imbalance toward the content creators, at the expense of the content consumers.

> just imagine how much more convincing of an argument there is to be made, based on its true underlying merits

Leaving aside the merits of your claim concerning the title containing a logical fallacy, HN's 80-character limit on the length of a submission's title can, at times, make this approach a bit difficult in practice.

Also, the policy of greatly preferring original titles.
Rather creative title given DCCP is about 10 years old now ...