Subject: Re: TCP Checksum Interoperability

From: "J. Noel Chiappa" <[email-masked]>
Date: Fri, 5 Apr 2002 17:09:52 -0500

> From: Joe Touch <[email-masked]>

    >> our interpretation of Robustness Principle applied to this problem
    >> dictated that we .. had to accept either ~(+0) or ~(-0) in received
    >> segments.
    >> Strictly speaking, either zero state is completely legal,

    > as per RFC1624 section 3, only one state (0x0000) is legal as the
    > complement of the checksum of non-zero data. ...
    > ..
    > The receiver is entirely justified in considering 0xffff as an error.

I would tend to disagree strongly with this last line, and agree with the
original statement above.

The TCP (and IP) checksum is defined as "the one's complement of the
one's-complement sum of the packet contents" precisely to allow the following
behaviour: one adds up the incoming packet, *including the checksum as it
sits* (i.e. without having to zero out that field), and then checks to see
that the result is all 1's - which is, as you point out, the only valid zero
value that a one's-complement summation process *of a packet* can compute.

(The only way to get all 0's as a sum of a one's-complement addition
process is to to sum a series of zero's - which a real packet will never
contain.)

Note that if the packet's check sum (i.e. the sum with the checksum field set
to zero) happens to come out to zero (i.e. all one's, before the complement),
then *either* value of zero in the checksum field of the packet will result in
an all-1's sum when the packet is checksummed.

I honestly don't understand why anyone's code even bothers to look at the
actual value in the checksum field of the incoming packet; just do the
checksum of the whole packet, and look at the result.

	Noel

PS: One does have to look at the incoming value for UDP, but that's different.

---

From: der Mouse <[email-masked]>
Date: Fri, 5 Apr 2002 19:21:24 -0500 (EST)

> one's-complement sum of the packet contents" [...]

> process is to to sum a series of zero's - which a real packet will
> never contain.)

...huh?  It depends on how you implement one's-complement arithmetic.

Consider, for example, "do two's-complement adds and reduce the result
mod 0xffff", which may be suitable on a machine with fast hardware mod,
and which can never produce 0xffff.

In 16-bit one's-complement arithmetic, 0x0000 and 0xffff are
equivalent, not only on input but also on output.  Trying to draw an
artificial distinction between them is not only unsupported by the
standard as far as I can tell but liable to break interoperability with
conformant implementations which don't draw that distinction.

> Note that if the packet's check sum (i.e. the sum with the checksum
> field set to zero) happens to come out to zero (i.e. all one's,
> before the complement), then *either* value of zero in the checksum
> field of the packet will result in an all-1's sum when the packet is
> checksummed.

...unless the packet checksumming is done in a way that generates
0x0000 instead of 0xffff when the sum is (one's-complement) zero.

> I honestly don't understand why anyone's code even bothers to look at
> the actual value in the checksum field of the incoming packet; just
> do the checksum of the whole packet, and look at the result.

With that I agree.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       [email-masked]
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

---

From: Joe Touch <[email-masked]>
Date: Fri, 05 Apr 2002 17:29:19 -0800

> ...huh?  It depends on how you implement one's-complement arithmetic.

See RFC1624. The definition of 1's complement arithmetic is not 
implementation dependent.

> conformant implementations which don't draw that distinction.

That issue is covered in RFC1624 and in RFC768.

> 0x0000 instead of 0xffff when the sum is (one's-complement) zero.

Again, see RFC1624.

>>do the checksum of the whole packet, and look at the result.

Because there's a difference - see RFC768.

Joe

---

From: der Mouse <[email-masked]>
Date: Fri, 5 Apr 2002 22:01:58 -0500 (EST)

> See RFC1624.

I believe 1624 is wrong, because it makes exactly the same mistake
you're making here.  What's more, to quote from it, "This memo does not
specify an Internet standard of any kind".

> The definition of 1's complement arithmetic is not implementation
> dependent.

True as far as it goes.  But in abstract one's-complement binary
arithmetic, all-0-bits and all-1-bits are completely equivalent, both
on input and on output; an implementation may produce either, at whim,
for zero results, and still be computing with one's-complement
arithmetic.

_That_ arithmetic is the one that is "not implementation dependent".  I
believe that's the arithmetic 793 specifies - and in that arithmetic,
the difference between all-0-bits and all-1-bits is a matter of two
completely equivalent representations of a single semantic value;
either may be generated for a zero result, according to convenience of
implementation, the parity of the cycle counter, or whether the CPU
happens to be mounted vertically.

>> Trying to draw an artificial distinction between them is not only
>> unsupported by the standard as far as I can tell but liable to break
>> interoperability with conformant implementations which don't draw
>> that distinction.

1624, aside from being all about *incremental* computation, is, I
believe, simply wrong; the arithmetic it describes - wherein all-0-bits
and all-1-bits are different - is not one's-complement arithmetic.

768 is irrelevant, since we're discussing TCP, and also because it
specifically goes to the trouble of specifying one of the two otherwise
equivalent representations of zero - it standardizes, for purposes of
UDP, a semantic difference somewhat akin to the one you're trying to
read into 793, which I believe just isn't there.  That is, 768 is
describing not one's-complement arithmetic but a specifically and
narrowly tailored extension of one's-complement arithmetic.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign