On 2014-01-15, Stuart Henderson <s...@spacehopper.org> wrote:
> On 2014-01-14, Richard Procter <richard.n.proc...@gmail.com> wrote:
>> 
>> I've a question about the new checksum changes. [...] 
>> My understanding is that checksums are now always recalculated when
>> a header is altered, never updated.
>> 
>> Is that right and if so has this affected NAT reliability? 
>> 
>> Recalculation here would compromise reliable end-to-end transport 
>> as the payload checksum no longer covers the entire network path, 
>> and so break a basic transport layer design principle.
> 
> That is exactly what slides 30-33 talk about. PF now checks
> the incoming packets before it rewrites the checksum, so it can
> reject them if they are broken.

Right -- so NAT now replaces the existing transport checksum
with one newly computed from the payload [0].

This fundamentally weakens its usefulness, though: a correct
checksum now implies only that the payload likely matches
what the last NAT router happened to have in its memory,
whereas the receiver wants to know whether what it got is
what was originally transmitted. In the worst case of NAT on
every intermediate node the transport checksum is
effectively reduced to an adjunct of the link layer
checksum.

This means transport layer payload integrity is no longer
reliant on the quality of the checksum algorithm alone but 
now depends too on the reliability of the path the packet 
took through the network.

I think it's great to see someone working hard to simplify 
crucial code but in light of the above I believe pf should 
always update the checksum, as it did in versions prior to 
5.4, as the alternative fundamentally undermines TCP by 
making the undetected error rate of its streams unknown and 
unbounded. One might argue networks these days are reliable; 
I think it better to avoid the need to make the argument. 
In any case the work I've found on that question is not 
reassuring [1].

best, 
Richard. 

[0] pf.c 1.863

On initial rule match: 
pf_test_rule()
  3445: pf_translate()
     3707: pf_change_ap()
        1677: PF_ACPY [= pf_addrcpy()] 
  3461: pf_cksum()
     6775: pd->hdr.tcp->th_sum = 0;
           m->m_pkthdr.csum_flags |= M_TCP_CSUM_OUT 
           (if orig checksum good) 

On subsequent state matching: 
pf_test_state() 
   ~4445: pf_change_ap() etc
   4471: pf_cksum() etc

[1] "Probably the strongest message of this study is that the 
networking hardware is often trashing the packets which are 
entrusted to it"

http://conferences.sigcomm.org/sigcomm/2000/conf/paper/sigcomm2000-9-1.pdf

Jonathan Stone and Craig Partridge. 2000. When the CRC and TCP checksum 
disagree. 
In Proceedings of the conference on Applications, Technologies, Architectures, 
and 
Protocols for Computer Communication (SIGCOMM '00). ACM, New York, NY, USA, 
309-319. 
DOI=10.1145/347059.347561 http://doi.acm.org/10.1145/347059.347561

Reply via email to