From 88a57dc98d9793d74f8e1c52729b50188d5a0b4f Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Tue, 8 Apr 2014 21:26:27 +0200 Subject: [PATCH] Fixed bug #36167 tcp server crash when client closes (maximum window) --- CHANGELOG | 3 +++ src/core/tcp.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f3015a80..8736ecc5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -100,6 +100,9 @@ HISTORY ++ Bugfixes: + 2014-04-08: Simon Goldschmidt + * tcp.c: Fixed bug #36167 tcp server crash when client closes (maximum window) + 2014-04-06: Simon Goldschmidt * tcp_in.c: Fixed bug #36210 lwIP does not elicit an empty ACK when received unacceptable ACK diff --git a/src/core/tcp.c b/src/core/tcp.c index 1af3d6b3..cdd08aef 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -650,12 +650,20 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) /* pcb->state LISTEN not allowed here */ LWIP_ASSERT("don't call tcp_recved for listen-pcbs", pcb->state != LISTEN); - LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", - len <= TCPWND_MAX - pcb->rcv_wnd); pcb->rcv_wnd += len; if (pcb->rcv_wnd > TCP_WND) { pcb->rcv_wnd = TCP_WND; + } else if(pcb->rcv_wnd == 0) { + /* rcv_wnd overflowed */ + if ((pcb->state == CLOSE_WAIT) || (pcb->state == LAST_ACK)) { + /* In passive close, we allow this, since the FIN bit is added to rcv_wnd + by the stack itself, since it is not mandatory for an application + to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */ + pcb->rcv_wnd = TCP_WND; + } else { + LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0); + } } wnd_inflation = tcp_update_rcv_ann_wnd(pcb);