tcp: LWIP_CHECKSUM_ON_COPY: fix adding data to retx segment

See bug #50914( TCP_CHECKSUM_ON_COPY when adding data to
retransmission): when adding data to an already transmitted segment
that has an uneven length, the checksum was wrong.

To fix this, tcp_output_segment has to restore seg->chksum_swapped
before returning.
This commit is contained in:
goldsimon 2018-02-12 12:38:17 +01:00
parent 7b6d2870ca
commit b5e67f142a

View File

@ -1426,6 +1426,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
err_t err; err_t err;
u16_t len; u16_t len;
u32_t *opts; u32_t *opts;
#if TCP_CHECKSUM_ON_COPY
int seg_chksum_was_swapped = 0;
#endif
if (tcp_output_segment_busy(seg)) { if (tcp_output_segment_busy(seg)) {
/* This should not happen: rexmit functions should have checked this. /* This should not happen: rexmit functions should have checked this.
@ -1543,6 +1546,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
seg->p->tot_len, TCPH_HDRLEN_BYTES(seg->tcphdr), &pcb->local_ip, &pcb->remote_ip); seg->p->tot_len, TCPH_HDRLEN_BYTES(seg->tcphdr), &pcb->local_ip, &pcb->remote_ip);
/* add payload checksum */ /* add payload checksum */
if (seg->chksum_swapped) { if (seg->chksum_swapped) {
seg_chksum_was_swapped = 1;
seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
seg->chksum_swapped = 0; seg->chksum_swapped = 0;
} }
@ -1568,6 +1572,16 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
pcb->tos, IP_PROTO_TCP, netif); pcb->tos, IP_PROTO_TCP, netif);
NETIF_RESET_HINTS(netif); NETIF_RESET_HINTS(netif);
#if TCP_CHECKSUM_ON_COPY
if (seg_chksum_was_swapped) {
/* if data is added to this segment later, chksum needs to be swapped,
so restore this now */
seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
seg->chksum_swapped = 1;
}
#endif
return err; return err;
} }