mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-27 06:14:09 +00:00
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:
parent
7b6d2870ca
commit
b5e67f142a
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user