From b5e67f142a74338427d7fd437392302672cc723b Mon Sep 17 00:00:00 2001 From: goldsimon Date: Mon, 12 Feb 2018 12:38:17 +0100 Subject: [PATCH] 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. --- src/core/tcp_out.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 9a5fc571..1ee7b9c8 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -1426,6 +1426,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif err_t err; u16_t len; u32_t *opts; +#if TCP_CHECKSUM_ON_COPY + int seg_chksum_was_swapped = 0; +#endif if (tcp_output_segment_busy(seg)) { /* 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); /* add payload checksum */ if (seg->chksum_swapped) { + seg_chksum_was_swapped = 1; seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); 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, pcb->tos, IP_PROTO_TCP, 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; }