refactor tcp_input a bit in preparation of a fix for bug #51937

(cherry picked from commit a8ac37f419)

# Conflicts:
#	src/core/tcp_in.c
This commit is contained in:
goldsimon 2017-09-09 21:41:06 +02:00
parent 1d04b06450
commit 66120f7d79

View File

@ -89,6 +89,8 @@ static void tcp_parseopt(struct tcp_pcb *pcb);
static void tcp_listen_input(struct tcp_pcb_listen *pcb); static void tcp_listen_input(struct tcp_pcb_listen *pcb);
static void tcp_timewait_input(struct tcp_pcb *pcb); static void tcp_timewait_input(struct tcp_pcb *pcb);
static int tcp_input_delayed_close(struct tcp_pcb *pcb);
/** /**
* The initial input processing of TCP. It verifies the TCP header, demultiplexes * The initial input processing of TCP. It verifies the TCP header, demultiplexes
* the segment between the PCBs and passes it on to tcp_process(), which implements * the segment between the PCBs and passes it on to tcp_process(), which implements
@ -404,17 +406,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
} }
recv_acked = 0; recv_acked = 0;
} }
if (recv_flags & TF_CLOSED) { if (tcp_input_delayed_close(pcb)) {
/* The connection has been closed and we will deallocate the
PCB. */
if (!(pcb->flags & TF_RXCLOSED)) {
/* Connection closed although the application has only shut down the
tx side: call the PCB's err callback and indicate the closure to
ensure the application doesn't continue using the PCB. */
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
}
tcp_pcb_remove(&tcp_active_pcbs, pcb);
memp_free(MEMP_TCP_PCB, pcb);
goto aborted; goto aborted;
} }
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
@ -532,6 +524,30 @@ dropped:
pbuf_free(p); pbuf_free(p);
} }
/** Called from tcp_input to check for TF_CLOSED flag. This results in closing
* and deallocating a pcb at the correct place to ensure noone references it
* any more.
* @returns 1 if the pcb has been closed and deallocated, 0 otherwise
*/
static int
tcp_input_delayed_close(struct tcp_pcb *pcb)
{
if (recv_flags & TF_CLOSED) {
/* The connection has been closed and we will deallocate the
PCB. */
if (!(pcb->flags & TF_RXCLOSED)) {
/* Connection closed although the application has only shut down the
tx side: call the PCB's err callback and indicate the closure to
ensure the application doesn't continue using the PCB. */
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
}
tcp_pcb_remove(&tcp_active_pcbs, pcb);
memp_free(MEMP_TCP_PCB, pcb);
return 1;
}
return 0;
}
/** /**
* Called by tcp_input() when a segment arrives for a listening * Called by tcp_input() when a segment arrives for a listening
* connection (from tcp_input()). * connection (from tcp_input()).