fix bug #21699 (segment leak in ooseq): add assert that all segment lists are empty in tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED state from LAST_ACK in tcp_process

This commit is contained in:
goldsimon 2007-12-04 20:41:12 +00:00
parent 3f96a15fd4
commit 8d3d08e814
3 changed files with 17 additions and 2 deletions

View File

@ -512,6 +512,12 @@ HISTORY
++ Bug fixes: ++ Bug fixes:
2007-12-04 Simon Goldschmidt
* tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last
data packet was lost): add assert that all segment lists are empty in
tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED
state from LAST_ACK in tcp_process
2007-12-02 Simon Goldschmidt 2007-12-02 Simon Goldschmidt
* sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET
If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now

View File

@ -1139,6 +1139,15 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
pcb->flags |= TF_ACK_NOW; pcb->flags |= TF_ACK_NOW;
tcp_output(pcb); tcp_output(pcb);
} }
if (pcb->state != LISTEN) {
LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
#if TCP_QUEUE_OOSEQ
LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
#endif /* TCP_QUEUE_OOSEQ */
}
pcb->state = CLOSED; pcb->state = CLOSED;
LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());

View File

@ -651,7 +651,7 @@ tcp_process(struct tcp_pcb *pcb)
tcp_receive(pcb); tcp_receive(pcb);
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
pcb->state = CLOSED; /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
recv_flags = TF_CLOSED; recv_flags = TF_CLOSED;
} }
break; break;