
TCP is an underspecified two-node consensus algorithm - r4um
https://morsmachine.dk/tcp-consensus
======
nh2
shutdown() and half-closes are not "archaic" features.

You need them to get even the basic stuff right (see
[https://blog.netherlabs.nl/articles/2009/01/18/the-
ultimate-...](https://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-
so_linger-page-or-why-is-my-tcp-not-reliable)) and you need it even more to
implement "modern" application layer protocols like HTTP2 (if you don't use
it, you get data loss bugs like this:
[https://trac.nginx.org/nginx/ticket/1250#comment:4](https://trac.nginx.org/nginx/ticket/1250#comment:4)).

------
lkarsten
I applaud the effort to hate on "smart" middleware proxies!

That being said, author gets no points for namedropping random distributed
systems algorithms and using tcp keepalives (2 hours minimum!) as an argument
against TLS terminating proxies.

Is there a reason to (as he says) "fully implement the protocol" in the proxy?
I battled with websockets through Pound last week, and it simply doesn't work
because the author took a non-postel stand on protocol specifics.

Having a protocol agnostic proxy like hitch (previously stud) fixed that
without losing functionality, and I expect it to age better as well.

~~~
zaarn
Sadly the internet isn't as nice. I've been to various hotels where the router
would silently drop keep-alive packets (but god forbid informing the packet
layer you do this!) and mangled DNS packets ("looking for mail.example.com?
Here is the answer for example.com" and "looking for doesnotexist.com? Here is
result for internalsearchengine.com which redirects you to a sponsored search
page with ads")

~~~
pixl97
And this is why encrypted DNS is a must.

~~~
zaarn
Even encrypted DNS will suffer because middleboxes with captive portals will
attempt to tamper it.

Unless you pipe it over TLS or HTTP in which case you run into problems with
not knowing why there is no connection in a captive portal (we obviously need
to fix captive portals, they're source of 90% of problems)

~~~
geofft
I learned recently about RFC 7710 which specifies a DHCP (v4/v6) and RA option
for "You're on a captive portal, here's the website you should visit before
you get access":
[https://tools.ietf.org/html/rfc7710](https://tools.ietf.org/html/rfc7710)

Do any of the major implementations of captive portals support it?

~~~
ttsda
RFC 7710 is only a proposed standard.

It has been implemented on a few captive portal solutions[1] but as far as I
know it is not understood by any client software.

[1] [https://github.com/coova/coova-
chilli/pull/274](https://github.com/coova/coova-chilli/pull/274)

~~~
vertex-four
RFCs are never anything other than proposed standards, or informational
documents. There is no point at which an RFC becomes a “recommended standard”
or some such thing.

All internet standards, from IP to HTTP, are proposed standards, it doesn’t
actually mean anything about whether they’re generally implemented or not.

~~~
mwcremer
Actually, they _do_ become standards:

[https://www.rfc-editor.org/standards#IS](https://www.rfc-
editor.org/standards#IS)

~~~
vertex-four
OH yeah, that started happening recently, I forgot about that.

------
teknopaul
I dont grok this, if tcp's model has fundamental problems how come the
Internet works. :)

The fact that a protocol technically is not perfect and causes jip for isps
does not mean the application layer has to get involved.

I've been writing tcp based apps for years and the stream abstraction has
never failed me. After reading this I dont see why I should change that
assumption? I have to rebuild connections occasionally but its never cost my
application so much that an alternative more complicated abstraction layer
made sense. I usually write req/response over tcp, an even more inaccurate
abstraction. Occasionally nonblocking code. Never have I wanted more
complexity than nio in my application layer.

Devs do know that "tcp is not a stream of bytes" but deliberately do not want
to get app code involved.

~~~
nvarsj
> I dont grok this, if tcp's model has fundamental problems how come the
> Internet works. :)

Depends on your definition of "works"! Just ask any gamer what happens when
someone starts using netflix while they're playing a game... For a lot of
people the internet doesn't work very well.

TFA is describing, I think, the issue of stale / dead connections - which can
be notoriously difficult to detect. Imagine you are building black boxes that
sit in peoples' homes, with a long running TCP connection to push
notifications to. With the state of the internet, it's very likely some
percentage of those connections will die without either side realizing it.
That's where the complexity comes in.

~~~
bringtheaction
Off-topic on my part here but I think it is so weird that people say “TFA”
when referring to the article in the way you are doing. I see this a lot on
HN.

IMO it would be natural to use “TFA” in the same way you would use “RTFM” —
when you are scolding someone for not having read what they should — but using
“TFA” as just a synonym for “the article”... that always throws me off.

~~~
xargon7
In a nice tone, it's "The Featured Article."

~~~
bringtheaction
Ah, clever, I like that :) Thanks!

------
kenforthewin
I suppose you could call it a two-node consensus algorithm, the same way
plugging a flash drive into your laptop is. Even after reading, I don't see
the benefit of viewing TCP this way.

~~~
tonyarkles
It's a layer under the "it's a bidirectional stream" abstraction. Having had
to debug gnarly TCP problems before (generally with semi-"intelligent" load
balancers), the two-node consensus concept is good to keep in mind.

Right now the "two-node consensus algorithm" idea has got me thinking more
about some of the nasty problems I've debugged and how to look at them through
that lens, especially considering partial partition tolerance. "Under what
circumstances can the TCP state machine on either end lose consensus, and how
will/won't it recover?"

------
peterwwillis
The problem is in thinking of an HTTPS request-response through proxies as a
single TCP connection. It isn't.

A TLS proxy is not a normal part of a layered TCP/IP connection. It's
literally in the name: "terminating" proxy. It stops the connection right
there. Anything after the TLS proxy is outside the scope of the initial
connection. Applications have to be engineered to pass on data from one
connection to another.

An example is stateful firewalls. Almost all stateful firewalls are NAT
gateways with rules. NAT gateways are designed to pass certain things from one
connection to another, but they are not simply unwrapping a layer from a
connection and passing it on: they maintain separate connections. _edit_
Apparently I'm wrong, as Netfiler apparently only defragments and then changes
addresses and ports, but firewall vendors basically keep independent
connections (for security reasons)

TCP is specified just fine _for consensus on a single TCP connection_. It
isn't specified for an HTTPS connection through middleware. Hence, such
middleware is complicated.

------
VMG
title is borked

