From 65d1f524237c2065815fbbde9d5656808ccf3a7d Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 21 Oct 2009 15:42:14 +0000 Subject: [PATCH] Changed fix for bug #27215 (TCP sent() callback gives leagin and trailing 1 byte len (SYN/FIN)) by decreasing pcb->acked appropriately --- CHANGELOG | 14 +++++++------- src/core/tcp_in.c | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1f03a6e9..861423f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -43,6 +43,13 @@ HISTORY ++ Bugfixes: + 2009-10-21: Simon Goldschmidt + * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and + trailing 1 byte len (SYN/FIN) + + 2009-10-21: Simon Goldschmidt + * tcp_out.c: Fixed bug #27315: zero window probe and FIN + 2009-10-19: Simon Goldschmidt * dhcp.c/.h: Minor code simplification (don't store received pbuf, change conditional code to assert where applicable), check pbuf length before @@ -52,13 +59,6 @@ HISTORY * dhcp.c: Removed most calls to udp_connect since they aren't necessary when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. - 2009-10-18: Simon Goldschmidt - * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leadin and - trailing 1 byte len (SYN/FIN) - - 2009-10-16: Simon Goldschmidt - * tcp_out.c: Fixed bug #27315: zero window probe and FIN - 2009-10-16: Simon Goldschmidt * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 2017c322..5fcb4cac 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -96,7 +96,6 @@ tcp_input(struct pbuf *p, struct netif *inp) struct tcp_pcb_listen *lpcb; u8_t hdrlen; err_t err; - u8_t old_state; PERF_START; @@ -289,7 +288,6 @@ tcp_input(struct pbuf *p, struct netif *inp) return; } } - old_state = pcb->state; tcp_input_pcb = pcb; err = tcp_process(pcb); tcp_input_pcb = NULL; @@ -315,11 +313,7 @@ tcp_input(struct pbuf *p, struct netif *inp) called when new send buffer space is available, we call it now. */ if (pcb->acked > 0) { - /* Prevent ACK for SYN or FIN to generate a sent event */ - if ((pcb->acked != 1) || ((old_state != SYN_RCVD) && - (pcb->state != FIN_WAIT_2) && (pcb->state != TIME_WAIT))) { - TCP_EVENT_SENT(pcb, pcb->acked, err); - } + TCP_EVENT_SENT(pcb, pcb->acked, err); } if (recv_data != NULL) { @@ -633,6 +627,11 @@ tcp_process(struct tcp_pcb *pcb) * we'd better pass it on to the application as well. */ tcp_receive(pcb); + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + pcb->acked--; + } + pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); if (recv_flags & TF_GOT_FIN) { @@ -877,6 +876,11 @@ tcp_receive(struct tcp_pcb *pcb) LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + pcb->snd_queuelen -= pbuf_clen(next->p); tcp_seg_free(next); @@ -917,6 +921,10 @@ tcp_receive(struct tcp_pcb *pcb) pcb->unsent = pcb->unsent->next; LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } pcb->snd_queuelen -= pbuf_clen(next->p); tcp_seg_free(next); LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));