[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: about the ULID in the TCP checksum
On 28-dec-2006, at 18:57, marcelo bagnulo braun wrote:
The problem here is that some intermediate system, such as a
firewall or a smart NIC, may take it upon itself to check the TCP
or UDP checksum and discard the packet if the checksum fails.
how common is this practice? is this widely used?
Certainly not with IPv6. But checksumming NICs are very common for
IPv4 so I'm sure we'll have those for IPv6 too in the future. And at
one point, PIX firewalls would truncate DNS packets that were longer
than 512 bytes, creating much mayham with EDNS0. So I have a healthy
suspicion of firewall builders.
For firewalls and the like, the best thing is probably either to
fully monitor the shim state so they can do this properly, or
forego such checking if a shim header is present.
yes, this is probably useful in terms of security also, just like
in the case to TCP connections, where the firewall can decide to
accept segments of connections for which the firewall have
previosuly seen SYN exchange
do you think we should add text about this? (if you do, please send
"Firewalls and other middleboxes SHALL NOT drop TCP, UDP and ICMP
packets with apparently incorrect checksums based on that fact alone
unless they implement (monitoring of) the full shim6 protocol and are
able to determine the checksum that must be present in a packet with
addresses rewritten by shim6."
For NICs a better solution would be to do an incremental checksum
verification and only over the ULP segment, so that the host stack
must complete the calculation by applying the increment from the
pseudo header, which can largely be cached, so the performance
advantages are almost completely preserved
i don't understand what do you mean by incremental checksum
verification... could you expand on this?
The checksum is defined as the one's complement of the one's
complement additions of the 16-bit words making up the pseudo-header
and the TCP/UDP/ICMP segment. So you could calculate it this way:
// 0 start
chksm = 0;
// 1 pseudoheader
for (i = 0; i < pseudo.length; i++)
chcksm = 1cmpadd(chcksm, pseudo.hdr[i]);
// 2 TCP
for (i = 0; i < tcp.length; i++)
chcksm = 1cmpadd(chcksm, tcp.data[i]);
// 3 check
if (1cmp(chcksm) == tcp.checksum)
As far as I can tell, NICs can do parts 0 - 2 and leave 3 up to the
IP stack. This method isn't compatible with shim6 because then the
NIC would have to be aware of the address rewriting. However, it
wouldn't be hard to do 0 and 1 in the IP stack, 2 in the NIC and 3 in
the IP stack again. Since the pseudoheader is always the same for a
session, this part can be pre-computed, so the only part that
actually requires real work is checking the TCP/UDP/ICMP segment,
which is exactly the part that still happens in the NIC, so
performance can be the same but now everything is shim-compatible.