On 2014-01-15, Stuart Henderson <[email protected]> wrote:
> On 2014-01-14, Richard Procter <[email protected]> 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