diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index dd88e1e5..1ee0e127 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -886,7 +886,8 @@ tcp_process(struct tcp_pcb *pcb) case FIN_WAIT_1: tcp_receive(pcb); if (recv_flags & TF_GOT_FIN) { - if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && + pcb->unsent == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); @@ -898,7 +899,8 @@ tcp_process(struct tcp_pcb *pcb) tcp_ack_now(pcb); pcb->state = CLOSING; } - } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && + pcb->unsent == NULL) { pcb->state = FIN_WAIT_2; } break; @@ -915,7 +917,7 @@ tcp_process(struct tcp_pcb *pcb) break; case CLOSING: tcp_receive(pcb); - if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + if (flags & TCP_ACK && ackno == pcb->snd_nxt && pcb->unsent == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_pcb_purge(pcb); TCP_RMV_ACTIVE(pcb); @@ -925,7 +927,7 @@ tcp_process(struct tcp_pcb *pcb) break; case LAST_ACK: tcp_receive(pcb); - if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + if (flags & TCP_ACK && ackno == pcb->snd_nxt && pcb->unsent == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ recv_flags |= TF_CLOSED;