Messages in this thread | | | Date | Tue, 16 Sep 2003 16:32:39 -0700 | From | Vishwas Raman <> | Subject | Re: Incremental update of TCP Checksum |
| |
Jamie Lokier wrote: > Richard B. Johnson wrote: > >>If I were to modify a low byte somewhere by subtracting 1, >>would I know that the new checksum, excluding the inversion, >>was 0x0000? No. It could be 0xffff. > > > You're right about information being thrown away, but wrong because IP > checksums are more rigidly defined than that. > > RFC1624 was written because the earlier RFC actually got this wrong. > > As long as at least one of the checksummed words is known to be > non-zero, 0x0000 is not a possible value. This is true of all IP checksums. > > There is only one possible value of the non-complemented sum: 0xffff. > > So when you subtract 1 from 0x0001, you get 0xffff. > > To do this right, instead of subtracting a word, you add the > complement of the word. After carry-folding, this works out right. > > Vishwas Raman wrote: > >>Are you then suggesting that instead of trying to do an incremental >>update of the tcp checksum, I set it to 0 and recalculate it from >>scratch? But I thought that doing that was a big performance hit. Isn't it? > > > You don't need to recalculate the sum. All routers modify the IP > header checksum when they decrement the TTL of a packet - it's a > widely used algorithm. Equation 3 from RFC1624 is correct :)
I was also under the belief that RFC1624 was handling this correctly.
> > Your code looks fine to me. Are you sure you're verifying the > checksum correctly?
This is how I am verifying the checksum. It seems to work in other cases. (by the way, I am working with the 2.4.20 kernel src code)
/* I do this check for only packets that are less than or equal to 76 bytes in length. And I make sure the packets that I am dealing with are less than this length */
int tcpFailoverVerifyChecksum(struct sk_buff* skb) { int len = skb->len - sizeof(struct iphdr); retValue = tcp_v4_check(skb->h.th, len, skb->nh.iph->saddr, skb->nh.iph->daddr, csum_partial((char *)skb->h.th, len, 0)); return retValue; }
Is the above function right? If not, what is the right way to verify the checksum of a tcp packet?
> > >> while (cksum >> 16) >> { >> cksum = (cksum & 0xffff) + (cksum >> 16); >> } > > > In general you need to add back the carry bits at most twice, btw. > > cksum = (cksum & 0xffff) + (cksum >> 16); > cksum += (cksum >> 16);
Ok...I will make the change... Thks...
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |