Hacker News new | past | comments | ask | show | jobs | submit login
Inappropriate TCP Resets Considered Harmful (2002) (ietf.org)
34 points by based2 on Jan 23, 2016 | hide | past | favorite | 14 comments



This should have a [2002] suffix.

A closely related contemporary document, talking about the then-new use of one of the reserved bits for Explicit Congestion Notification (ECN): http://www.icir.org/floyd/ecn.html


Came here to say the first line; +1


> RFC 793 and RFC 1122 both include Jon Postel's famous robustness principle, also from RFC 791: "Be liberal in what you accept, and conservative in what you send."

Which is complete nonsense that doesn't justify anything and only casts suspicion on the muddled reasoning.

The correct principle is: be conservative in what you send, and loudly reject nonconforming, out-of-spec input.

"Be liberal in what you accept" results in situations like some broken piece of HTML, CSS or JavaScript working in seven diffrent ways on seven different browsers.

> However, the phrasing in RFC 793 does not permit sending resets in response to TCP packets with a non-zero Reserved field, as is explained in the section above.

Non-zero in a reserved field that has no meaning now, and should be loudly diagnosed as an error until such a time that it has a meaning. Resetting a connection is a good facsimile of such a diagnostic.

Just like in a C program if you use a name like __foo that is reserved, cows can fly out of your nose; but diagnosing it is better: diagnosing it now, while it has no meaning. Once __foo gets a meaning, it will be too late.

If connections are reset when their machines send packets which infringe on reserved fields, they will quickly learn to fix things so that their machines stop sending that. Then when the time comes, it will be possible to actually assign a use to a previously reserved field.

If everyone uses a reserved field willy-nilly and never gets punished with RST's, it will be difficult to impossible to introduce a standard new use for that field. Hosts receiving the field will not know whether they are getting a genuine request with the new meaning of the field, or whether they are getting garbage which is a continuation of the widespread abuse of the field. And at that time, it will no longer be possible to send a RST due to the ambiguity, right? The time to spew a RST in the face of the offending systems is today.

The original meaning of RST is to inform the sender that they are sending data for a connection that doesn't exist. Sending a RST for a nonzero value of a field is a logical extension of this: it's a piece of data destined for something that doesn't exist: namely, the meaning of that field! The bits aren't, ahem, connecting with a meaning. See?

Really, what is the point of a rule that is not enforced? If sender are supposed to leave something zero, but nobody checks that and takes any action against nonconforming senders, why document such a requirement at all?


> Bullshit. Non-zero in a reserved field that has no meaning now, and should be loudly diagnosed as an error until such a time that it has a meaning.

This makes no sense. You must treat a reserved field as meaningless and having no consequence, otherwise eventually, when it does have meaning and your old code is looking at packets, you're going to start "loudly diagnosing" all over the place.


You have to replace that old code, obviously. Or, much better yet, configure it not to do the diagnosing any more. That's a separate concern, one of "what happens if this field starts being used, but old code is still in wide deployment". It doesn't negate the basic principle.


Except you have to assume old code will be in deployment after the new code exists. The whole point of "reserved" fields is to tell old code not to freak out if it sees new code using that field but doesn't understand it.


Yes, of course, so when you're writing the strictly validating code, it has to be written with the assumption that although field must be zero now, that change in the future. And when it changes, the same code image will still be deployed in many places. Therefore, the validation cannot be hard coded; it has to be configurable so that the behavior can change to reflect the changed status of the field. This configurability has to be properly verified: does the equipment really stop validating and sending RST's in the "off" configuration for that field.

RFC3360 says that sending RST is bad, and everyone please change that. It is written based on the fear that the rejecting behavior is hard-coded in some binary machine language images, so that if fixes aren't deployed now to get rid of the behavior, then when it becomes necessary to start using the field, it will be impossible, due to the need to roll out a massive upgrade to all sorts of networking equipment all over the world.

The topic should be: "RST-generating checks that cannot be disabled without upgrading the software image on the networking equipment are harmful".


A while back I needed to re-implement the wheel, an extremely minimalist routing protocol. I asked my smart friends what to do and one of them helpfully gave me a really good book by a guy that spent about 30 years implementing networking 'stuff'. Reading through it he pointed out that at the bits/bytes level a lot of protocols are broken because of the lack of a version field[1].

If you have proper versioning you can say; for packet format 001, the field foonarg[1:3] must be 000. And if it isn't it must treated as garbage and tossed. If you don't have versioning, you're kinda stuck with a bunch of ad-hock methods. Stuff like the this unused (we hope) bit in this field is never set this way for this format. Or this packet is 87 bytes long thus it must be this format. head desk

If you ever have to design binary or even text based data format that needs to be shared add a version field, you'll hate yourself less later.


A lot of things need to be considered when designing a new protocol.

Versioning is clearly not enough: IP for example has many version fields, but that's not helping IPv6's adoption. You may not be able to "replace all the old versions" if your protocol becomes popular, so you need to consider how you will update it anyway.

Tags are worth study: If ECN had been implemented as a new IP option instead of appropriating a bit that "everyone should be ignoring" we would've avoided a lot of problems a few years ago.

Differentiating between "must implement to operate" and "may implement" is also useful. Sometimes you can add this with a flag or special notation (e.g. PNG and RIFF), but for protocols you can also use negotiation: Telnet's WILL/WON'T/DO/DON'T/CAN/CAN'T system, for example.

Specifying failure cases is also good: To make sure people implement reliable systems, I often design into the spec the retry protocol and have a mode (used in interoperation) that causes random failures so they have to implement the retry protocol correctly.


Could you shed some light on which book you are referring to?


Digging through my piles of books, it's this one, outdated if you're interested in current stuff.

Interconnections Bridges Switches and Internetworking Protocols by Radia Perlman

http://www.amazon.com/Interconnections-Bridges-Switches-Inte... https://en.wikipedia.org/wiki/Radia_Perlman


Among other things, this specifies dropping of packets with the "evil bit" set.

It sounds like this is not the only use that the reserved fields have been applied to. Zeroing a field is certainly not ideal for the liberal acceptance proscribed by Postel's law.


I'm... clearly not parsing any of your statements correctly.

As I read it, one of things the linked IETF BCP document does is to implore authors and configurers of TCP software to ignore and pass through -unchanged- TCP options that they don't understand, rather than to consider them invalid and abort the connection.

Did I misunderstand the linked BCP?


RFC 793 shouldn't have been so strong as to say that the "reserved field MUST be zero". If I was trying to implement the standard, I would consider such a packet invalid in the same way that a packet with an invalid checksum is invalid. You can't use such strong language and then blame implementations for taking such language seriously.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: