To follow up on this issue. The offending piece of code that is generating the 0xFFFF as the TCP checksum is this (lines 1137-1147 in tcp_out.c):
/* rebuild TCP header checksum (TCP header changes for retransmissions!) */
acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip),
&(pcb->remote_ip),
IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4);
/* add payload checksum */
if (seg->chksum_swapped) {
seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
seg->chksum_swapped = 0;
}
acc += (u16_t)~(seg->chksum);
seg->tcphdr->chksum = FOLD_U32T(acc);
If acc happens to have a value equal to seg->checksum, for example acc=0x8E93 & seg->checksum=0x8E93, (which can happen given the right set of values) one gets acc += ~acc, which always results in 0xFFFF. The FOLD_U32T has nothing to do and the 0xFFFF is set as the seg->tcphdr->chksum. Which is wrong? Am in missing something?
Anyone able to enlighten me as why this isn't a coding error?
Shouldn't there be something to ensure 0xFFFF is converted to 0x0000?!
Thanks.
Niall.