NoTCP
notcp.io
notcp.io
Actually, UDP was "un-designed" by me and others.By this I mean that
UDP was the final expression of a process that today we would call
"factoring" an overcomplex design. Originally, the ARPANET end-to-end
protocol NCP was a "kitchen sink" oriented toward providing remote
teletype-centric access using the "telnet" protocol and the "FTP"
protocol to remote machines over a packet network.
A group of us, interested in a mix of real-time telephony, local area
networks, distributed operating systems, and communications security,
argued for several years for a datagram based network, rather than a
virtual circuit based network. The group involved me, John Schoch and
Yogen Dalal of Xerox PARC, Danny Cohen of ISI (now at Caltech, I think),
and Steve Crocker, with Jon Postel as a supporter, and Vint Cerf and Bob
Kahn as neutral referees.
UDP was actually "designed" in 30 minutes on a blackboard when we decided
pull the original TCP protocol apart into TCP and IP, and created UDP on
top of IP as an alternative for multiplexing and demultiplexing IP
datagrams inside a host among the various host processes or tasks. But it
was a placeholder that enabled all the non-virtual-circuit protocols since
then to be invented, including encapsulation, RTP, DNS, ..., without having
to negotiate for permission either to define a new protocol or to extend
TCP by adding "features".
[1] "udp and me" http://www.reed.com/blog-dpr/?page_id=6A rhetorical question: if other protocols are better at this or that, what forces have made TCP the only transport protocol of note for so long?
Well, in TCP, window scaling needs to be OS-global to avoid flapping. This means TCP lives in the kernel. And this means, if you want a protocol with any property similar to window scaling, it also needs to live in the kernel.
Which is to say, if you want your protocol to do anything that requires machine-level resource pooling, it has to be machine-global, not app-local.
This is true trivially if your protocol wants to live in layer-4; anything peer to TCP or UDP has to have its own kernel driver in every major OS, and in every major firewall/load-balancer/NAT appliance.
But even when you build on top of UDP on "layer 4.5", you're still under the same constraint. Even if you're not in the kernel, you still need a single-instance-per-machine daemon or somesuch. You still need to install something as root. The 1993-era user story of "my ISP just told me to enable something called NetBEUI!?" still applies.
The reason much of this will be decreasingly relevant?
Unikernels.
If your app has guaranteed 1:1 ownership of a "machine", then your app can speak whatever wire protocols it likes; an app-level resource pool is a global resource pool.
Unikernels talking to other unikernels can easily make use of new layer-4 protocols. That's exciting!
Combined with the coming wave of "cloudlets" (small VMs paired to an individual customer of a device manufacturer or ISP, where the customer's mobile devices and home network use the cloudlet as a featureful VPN proxy), these new layer-4 protocols can be tunneled out to customers, too, avoiding any and all intervening muck.
The next 10 years of networking will be interesting!
http://www.connectify.me/blog/taking-google-quic-for-a-test-...
things might have improved, but over slow lossy links, its really not worth the hassle.
the OC alludes to the point that UDP requires less kernel intervention, which means you can do more funky things.
Compared to HTTP things like QUIC make perfect sense - especially when you consider all the RTT wasted on pipelined connections to the same site. You're only opening all those sockets because they're not multiplexed in any manner - your browser wants a JPG, grab the JPG. Your browser wants another, do it again...
So while this is light hearted, there's some validity to next gen web protocols that are more adapted to how the data is consumed.
Agreed SPDY and HTTP/2 have multiplexing built in - but so does QUIC.
From the design doc: https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqs...
"This is a working document, for group discussion and editing, which we expect to evolve into a somewhat fleshed out design document. The expectation is that we will flesh out a design for a tunneling protocol, running atop UDP, which can multiplex a large number of streams between two endpoints (a client, which initiates the overall connection, and a server). Each stream may, for example, be nearly equivalent to an independent TCP connection."
Edit:
And this...
"Pairs of IP addresses and sockets are finite resources. Today, too many distinct connections are routinely made between clients and servers, utilizing a multitude of sockets, and often carrying redundant information. A multiplexed transport has the potential for unifying the traffic and reducing the port utilization count. A multiplexed transport can unify reporting and responses to channel characteristics (packet loss, etc.), and also allow higher level application protocols (such as SPDY) to reduce or compress redundant data transmissions (such as headers). In the presence of layer-3 load-balancers, a multiplexed transport has the potential to allow the different data flows, coming and going to a client, to be served on a single server."
Conversely, any hints and clues to window sizes that are provided by network packets can be read from a user process and so don't need to reside in the kernel either.
Rather, the need for cooperation actually extends to groups of physical machines sharing a network connection too. Indeed, that's the key insight underlying objectivist mouse-based congestion control:
The controlling principle behind almost all congestion control algorithms is that a single node can derive the properties of the path between itself and the other end by using the state of the transfer visible only on that one node. Once you reject that principle, any algorithm you come up with will quickly become unscalable.
http://en.wikipedia.org/wiki/Route_flapping
and I couldn't work out how this related to TCP living in the Kernel.
Not trolling, real question. Thanks in advance.
with UDP, that layer of ACK, ordering and rate limiting is gone.
if you want to send a million packets a second to 56k modem, sure the kernel isnt going to stop you.
Whilst it might be possible to have per TCP connection windowing parameters, I doubt it'd be very efficient.
If you had kept going here and explained why you doubt that, you would have answered the parent's post.
TCP windows is strongly related to time and buffer capacity and consumption.
If you don't control the time, you can't control tcp-windows. I suppose.
It is simple to use and good enough for most purposes. Streams and games for a long time already.
Well, another one is that rather a lot of things block anything that isn't TCP, DNS, UDP, and anything else that isn't the bare minimum for "the web" to work. They'll even go so far as to pick out which types of ICMP messages to pass through.
The internet at large has been sitting on SCTP for a very long time, because nobody expects SCTP to be able to get through firewalls. (On that note, perhaps the solution is to reformulate SCTP in terms of UDP, as that's what everybody else seems to be doing.)
UDP is quickly becoming the base protocol for "I don't want TCP but I do need something that gets through firewalls". Sort of like how so many things float on port 80 or HTTP that don't really need to, but it's what can get through firewalls and such.
Exactly right. No need to invent a new protocol number in the IP headers. UDP is the perfect vehicle for custom protocols. And once you start experimenting with a somewhat intelligent custom protocol, it's amazing how easy it is to beat even well tuned TCP stacks on average over a large number of users. This is especially true, by large large margins, over mobile networks.
Sorry but this is a huge assertion with absolutely no supporting evidence or argument. What exactly do you mean by "flapping"? Why do we need to avoid it? And why does a protocol need to live in the kernel to avoid flapping?
I suspect those assertions are based on an assumption that congestion control gets done in a cooperative manner across connections. (I'm assuming the "window" here is congestion window.) I've never seen or heard of a TCP stack that somehow takes into account all TCP flows in a system. As a matter of fact, even if that was the case, it would be too limited a view of the responsibilities of TCP congestion control.
The congestion control algorithms are working on a global picture of congestion... as in across the entire network path between the two communicating nodes. Various cc algorithms (reno, vegas, bic, cubic etc.) are using their own techniques to probe the network path between the two endpoints (either using packet drops or round-trip delay increases as a signal of congestion). As such, the concern of congestion control extends beyond just the one node where the algorithm happens to be running. But the important point here is that each node on the network uses only the signals available locally at that node. And for the purposes of this argument, you can consider each of the TCP endpoints on a single machines as an independent node.
I don't see any convincing case why two separate instances of these state machines can't be running independently in kernel and user space. Since ultimately, if they're competing for bandwidth over a common, narrow part of the pipe, they'd each use their own congestion signals to arrive at the same conclusion (assuming the protocols are designed for fairness).
Taking into account all flows is indeed not useful. But there's some useful middle ground between "all flows" and "each flow completely separately".
At work we've got a transparent proxy with an integrated userspace TCP stack. When it's installed in a mobile operator's network, all of that operator's subscriber traffic will be going through it. Now, for each subscriber all the flows between the terminal and the proxy will be in the same "congestion domain"; they're guaranteed to be competing over the same network resources (whether it's backhaul or radio capacity). And in fact for the scarcest resource of the radio capacity each subscriber is essentially in their own congestion domain due to the way the radio base stations scheduling algorithms work. Having the custom TCP stack treat all of a single user's flows as a single unit rather than individually is a big win.
(The original claim that TCP must in the kernel for "window scaling" doesn't make any sense to me, no idea of what it could be referring to).
Well done.
In fact, UDP servers typically handle a large number of clients with a single socket. So each `recv` system call on the UDP socket pulls a message from a different client. The source IP and port number could be used to do the basic matching of the message to the client, but then subject to more checks.
This can end up being more robust than TCP. TCP can be subject to IP spoofing, and because it doesn't have the crypto, this spoofing can interfere with the session (a form of DDoS): e.g. inject bytes into the TCP stream, which then screw up the stream so that it has to be scrapped and reconnected. A UDP based protocol can robustly drop garbage, so that the session is not affected (except for the network and CPU usage of these spoofed packets).
Spoofing discussion is actually the very first paragraph in its security document: https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblH...
UDP is really fast, multicast! and when you get a message its all there (not a stream) . For large messages breaking them/ reassembling them into chunks is a pain.. By the time you do all the processing/ handshaking you end up back at TCP.
Interestingly the size limit is around 64k and varries slightly between Solaris, hpux and linux.
When you write a protocol using TCP you inevitably have to send the "content length" as part of the protocol, and then you have to account for spoofing of that number and other ways an attacker can create a denial of service, and also account for breaks in transmission. It's a pain in the ass for anything where you'd want to send small messages.
(although I'm old enough to remember whole computers with 1 UDP packet worth:64K bytes of memory, that isn't alot today)
The loop and keep reading of tcp does gets tiresome, and if the sender goes down broken pipe...Memory allocation for the read...
We used a lot udp and udp multicast, and it was great to be able to fire up a diagnosing tool to join the multicast group and listen in. Though in multicast the OS networking stack handles keeping your subscription, with no intervention from the software.
How do you get more widespread adoption? It's been 15 years.
The only people who would buy into this are people who have no experience with networking, and thus this would only affect their probable usage of libraries down the road with the wrong intentions.
Hell, I don't even know who this is really suppose to address. My best guess is people with very little knowledge of network protocols and their usages.
Seriously, how can you read "just as the Reactive Manifesto reminded us that new branding can give a youthful glow to decades-old ideas" as anything but funny?
UDP can do things TCP can't do, I think it's worth exploring.
> just as the Reactive Manifesto reminded us that new branding can give a youthful glow to decades-old ideas
Well done.
I wouldn't want to write HTTP over UDP, but neither would I want to send telemetry data ('{"timestamp":343821902, "value": 43}') over TCP. UDP is brilliant for systems where you're more concerned about tracking the current state of things than accurately replaying the last n set of transactions.
This is fine, HTTP is probably the largest layer 7 protocol on the internet, but if you were to design a layer 7 protocol that needed a lot of the features that TCP provides it would be quite dump to reimplement them yourself on top of UDP.
Many, many applications deal much better with loss than they do with delayed retries. You don't want a VOIP app to perfectly recreate what the other part said 30 seconds ago, games usually only care about current state, and so on. In many of those cases, TCP is the wrong choice but a lot of people use it out of familiarity.
Remember, UDP came after TCP. One isn't "better" than the other and they serve different requirements.
Would you rather wait for a transmission of the missing position update 1 sec ago or just forget about it and continue processing the next one ?
In this context, you'll prefer the second option. It will probably cause a visual glitch but the game can go on, and players will say "lag" :)
It still won't change the fact that application needs won't always match TCP exactly. And that's the whole point.
you care about the data, you want it to arrive in order, and you need it arrive. You want to be notified if there is a problem at the other end. You want the data sent to match exactly the data delivered.
File transfer, simple protocols, advanced critical protocols. Anything where the dev doesn't want to think about how to account for packet loss. Its already done for you in a standard interface.
Why you want UDP:
You want the latest packet of data, and you want it now. it doesn't matter if you lose a few packets. Telephony is the classic example. if you loose a frame its not the end of the world. Streaming video is another, Use FEC to cope with loss.
Tedious real world analogy:
When you send a letter or a parcel, you have two options: Send it recorded, and pay slightly more per go, but not have the worry about phoning up the recipient to see if they received it.
However if the letter is of little worth (like a flyer or something similar) then the notification and or guarantee that it has/will arrive is a pointless cost.
In addition to reliability, TCP provides congestion control which provides approximate fairness of bandwidth utilization per connection. Fairness here meaning given a limited pipe of size W each connection gets a W/N slice of the pipe's available bandwidth. I don't know that I'd like to live on an internet where every hipster made their own decision about how to handle congestion control, see also congestive collapse.
Which is why the "default" protocol for most things is still TCP.
Unless they had access to a tier 1/2 network provider it'd be mostly harmless I suspect. They'd spam their local gateway. "Look I can send 300k packets a second over standard DSL"
But yes, TCP is generally a good thing.
And, with a bunch of per-site monitoring frontends with batching, compression and deduplication, thrift/protobuf and long-running connections, the TCP overhead is meh.
Serious exceptions, sure, retry. But serious exceptions are rare. What's not rare is sampled memory usage, cpu usage etc..
"We follow in their Chukka-booted footsteps by challenging the comforts of the ubiquitous Transmission Control Protocol and recognizing the well-deserved renaissance of artisanal protocols built on UDP. We didn’t start this fire, we’re just calling it what it is: the NoTCP movement"
I'd admit to being too dumb to parse the exact sentiment behind that paragraph. Though it does sound somewhat like sarcasm to me.
Then in the rest of the paragraphs, he actually goes on to make a pretty good case of why one might want to get rid of TCP (especially from under the complex beast that HTTP/2.0 is with it's own flow-control, multiplexing etc.)
For what it's worth, I wrote my own manifesto against using TCP in all cases a few weeks ago. But this one is geared very specifically towards the needs of mobile native apps.
> Sign the manifesto: http://notcp.io . If you can figure out a way to sign it using UDP, let us know.
It's pretty clear they know they are being ridiculous.
That said, it is nice to have reminders that there are alternatives to the overwhelmingly popular default. Kids these days grow up using TCP so much they become devs who can't conceive of whole categories of software that don't happen to line up with the tradeoffs designed into TCP. Heck, seems like most people have a hard time remembering that there's more to the Internet than HTTP.
UDP while is very simple from design point of view is actually very complicated to use if you plan to do something more than just send few packets.
The issue is primarily, that you don't have a feedback loop that tells you the rate at which you should send the data. Also badly written applications that use UDP can create congestion collapse in a network (no congestion control/avoidance).
For example why not allow UDP from Javascript in the browser with CORS like protections to limit DOS attacks. I.e., only allow UDP connections back to the origin unless the server explicitly allows non-origin access from the requesting domain.
This approach seems a lot simpler and opens the doors to all kinds of improvements not just those designed into HTTP/2.
(Though there's still plenty of gear still using TDM or ATM)
Of course UDP is useless in many cases, but it does have its uses.
It looks like this is just mocking people who can't follow the "don't reinvent the wheel" rule, but why assume that all types of wheel are already invented? P2P networking needs fine control. Bare metal is not here for nothing.
For example, most modern-day commercial firewalls more closely resemble a NAT machine than anything else. All your packets may be changed as they pass through in order to verify their authenticity and integrity once they return. And if the protocol isn't supported, it may not be passed through at all.
If you want to support existing networks, it has to be either TCP or UDP. In order to support next-generation firewalls, you also have to use the OS's tcp/ip stack. In order to support typical commercial network/proxy configuration, you have to use a higher level protocol like HTTP. And this isn't even talking about the "features" of the different protocols and how they're handled.
A replacement for TCP has to be done by a standards body and accepted by vendors, or [at least] half of the world will never be able to use it.
"are you serious?
Oh, absolutely. There are plenty of successful, purpose-built protocols that used UDP before it was cool: DNS, NTP and RTP, to name a few."
DNS and NTP are built over UDP because they are light weight applications. RTP is built over UDP because you don't care about loss. Hell even DNS still uses typically uses TCP when doing zone transfers between DNS servers because of the amount of data involved.
What point is the author trying to make with this statement?
All technology is a tool, use the right tool for the job and move on.
I did but I can still see my comment as normal.
For the moment, we still notice that there's something that we're supposed to read.
Sorry for the rant, that's the final straw...
Care has even been taken to include the light and bold variants of the font, but not the regular one.
Pity. I'd really like to know what the person is trying to say.
They are using the same template as this group: http://opengrok.github.io/OpenGrok/ ... I'd really like to meet the person who made this - I bet he can see through walls. (it's here: https://github.com/orderedlist/minimal)
might as well plug my site: http://unreadable.website
[0] - http://nacr.us/media/pics/screenshots/screenshot--11-33-12.p...
[1] - https://addons.mozilla.org/en-US/firefox/addon/read-easily/
If it's a site that's worth reading I'll overide the CSS with Stylish otherwise I'll just not bother reading the site. It's funny how many sites fall into the later category.
* What is the lighting condition of your work environment?
* What kind of screen do you use?
* What does your "normal" desktop look like?
* What kind of programming do you do (scientific? web dev?)?
I have assumptions about this and I want to see how they pan out.
I think the lowest contrast that is still somewhat acceptable for me is the solarized theme, but even that goes over too close to the low contrast end: http://ethanschoonover.com/solarized
so ... you're quitting the internet?
I have a 3-year old PR here to fix it. Feel free to +1 :) https://github.com/orderedlist/minimal/pull/2
But for the NoTCP site, I have a sneaking suspicion that this may have resulted, in-part, from only previewing the site on HiDPI (aka Retina) displays. It's an increasingly easy trap to fall into, especially for "casual" designers. My eyesight kinda sucks, but I've noticed that really good modern HiDPI displays make much lighter fonts comfortable than I'd otherwise be able to use.
||googleapis.com
for a more beautiful web. Nothing of value is lost.Node.js is hardly bare metal and non-blocking IO is hardly new; Unix programmers have been writing select()/event-loop and poll()/epoll() servers for decades. The presentation of this false dichotomy between Node.js representing "bare-metal" at one end and readable code at the other suggests the author is some type of opinionated Ruby/Rails hipster programmer upset that his pet language and framework is falling out of favor, and in no small part because of its abysmal performance.
I mean, I can hardly imagine "node.js" and "bare-metal performance" being in the same phrase and not being sarcastic.
I don't care. I don't care about TCP, I don't care about UDP, I only care about QUIC because I'm a Google fanboy.
I shouldn't have to care about this. All I want is some very fast, very reliable underlying protocol for my web apps and api endpoints to run on.
You don't have the privilege of not caring about, at least if you're in the position where you have to make decisions involving it. Quick: what's best, ints or strings? That entirely depends on how you want to use them, doesn't it?