From f48c71e17f4b639161950663ea8891cc9e3e8b37 Mon Sep 17 00:00:00 2001 From: David Girault Date: Wed, 20 Sep 2017 20:50:03 +0200 Subject: [PATCH] altcp_tcp: free altcp_pcb struct in altcp_tcp_close() Signed-off-by: goldsimon --- src/core/altcp_tcp.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/core/altcp_tcp.c b/src/core/altcp_tcp.c index cbbc422e..72be8153 100644 --- a/src/core/altcp_tcp.c +++ b/src/core/altcp_tcp.c @@ -152,6 +152,17 @@ altcp_tcp_err(void *arg, err_t err) } /* setup functions */ + +static void +altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb) +{ + tcp_arg(tpcb, NULL); + tcp_recv(tpcb, NULL); + tcp_sent(tpcb, NULL); + tcp_err(tpcb, NULL); + tcp_poll(tpcb, NULL, tpcb->pollinterval); +} + static void altcp_tcp_setup_callbacks(struct altcp_pcb *conn, struct tcp_pcb *tpcb) { @@ -288,7 +299,22 @@ altcp_tcp_close(struct altcp_pcb *conn) } ALTCP_TCP_ASSERT_CONN(conn); pcb = (struct tcp_pcb *)conn->state; - return tcp_close(pcb); + if (pcb) { + err_t err; + tcp_poll_fn oldpoll = pcb->poll; + altcp_tcp_remove_callbacks(pcb); + err = tcp_close(pcb); + if (err != ERR_OK) { + /* not closed, set up all callbacks again */ + altcp_tcp_setup_callbacks(conn, pcb); + /* poll callback is not included in the above */ + tcp_poll(pcb, oldpoll, pcb->pollinterval); + return err; + } + conn->state = NULL; /* unsafe to reference pcb after tcp_close(). */ + } + altcp_free(conn); + return ERR_OK; } static err_t