From db4844e3f0ced9268a17f0b0265f65cc45f2c59c Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 17 Dec 2014 09:26:17 +0100 Subject: [PATCH] fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for no-copy data with odd length --- CHANGELOG | 4 ++++ src/core/tcp_out.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index f30d2f34..d1257cd2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -143,6 +143,10 @@ HISTORY ++ Bugfixes: + 2014-12-17: Simon Goldschmidt + * tcp_out.c: fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for + no-copy data with odd length + 2014-12-10: Simon Goldschmidt * sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index c33a2617..23848ccf 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -79,6 +79,12 @@ #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 #endif +/* Allow to override the failure of sanity check from warning to e.g. hard failure */ +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK +#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL +#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg) +#endif +#endif /* Forward declarations.*/ static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); @@ -566,6 +572,10 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) #if TCP_CHECKSUM_ON_COPY /* calculate the checksum of nocopy-data */ chksum = ~inet_chksum((u8_t*)arg + pos, seglen); + if (seglen & 1) { + chksum_swapped = 1; + chksum = SWAP_BYTES_IN_WORD(chksum); + } #endif /* TCP_CHECKSUM_ON_COPY */ /* reference the non-volatile payload data */ p2->payload = (u8_t*)arg + pos; @@ -1204,7 +1214,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) seg->tcphdr->chksum = FOLD_U32T(acc); #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK if (chksum_slow != seg->tcphdr->chksum) { - LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, + TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL( ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", seg->tcphdr->chksum, chksum_slow)); seg->tcphdr->chksum = chksum_slow;