From 3f6b4280d42831d44c2502b79aa7d25424b23496 Mon Sep 17 00:00:00 2001
From: David Cermak <cermak@espressif.com>
Date: Sun, 4 Sep 2022 10:35:12 +0200
Subject: [PATCH] tcp/close: Fix clean socket closure when lingering

2.1.3-esp: 316cfc17 tcp/close: Fix clean socket closure when lignering
---
 src/api/api_msg.c      | 8 ++++++--
 src/core/tcp.c         | 8 +++++++-
 src/include/lwip/tcp.h | 2 ++
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/api/api_msg.c b/src/api/api_msg.c
index 546cdff41..5aec8dd1b 100644
--- a/src/api/api_msg.c
+++ b/src/api/api_msg.c
@@ -898,7 +898,7 @@ netconn_drain(struct netconn *conn)
           /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
           /* pcb might be set to NULL already by err_tcp() */
           /* drain recvmbox */
-#if ESP_LWIP
+#if ESP_LWIP && LWIP_NETCONN_FULLDUPLEX
           newconn->flags |= NETCONN_FLAG_MBOXINVALID;
 #endif /* ESP_LWIP */
           netconn_drain(newconn);
@@ -1032,7 +1032,11 @@ lwip_netconn_do_close_internal(struct netconn *conn  WRITE_DELAYED_PARAM)
     if ((err == ERR_OK) && (tpcb != NULL))
 #endif /* LWIP_SO_LINGER */
     {
-      err = tcp_close(tpcb);
+      err = tcp_close_ext(tpcb,
+#if LWIP_SO_LINGER
+                          /* don't send RST yet if linger-wait-required */ linger_wait_required ? 0 :
+#endif
+                          1);
     }
   } else {
     err = tcp_shutdown(tpcb, shut_rx, shut_tx);
diff --git a/src/core/tcp.c b/src/core/tcp.c
index ea95ffeef..5c9d20f79 100644
--- a/src/core/tcp.c
+++ b/src/core/tcp.c
@@ -482,6 +482,12 @@ tcp_close_shutdown_fin(struct tcp_pcb *pcb)
  */
 err_t
 tcp_close(struct tcp_pcb *pcb)
+{
+  return tcp_close_ext(pcb, 1);
+}
+
+err_t
+tcp_close_ext(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
 {
   LWIP_ASSERT_CORE_LOCKED();
 
@@ -495,7 +501,7 @@ tcp_close(struct tcp_pcb *pcb)
     tcp_set_flags(pcb, TF_RXCLOSED);
   }
   /* ... and close */
-  return tcp_close_shutdown(pcb, 1);
+  return tcp_close_shutdown(pcb, rst_on_unacked_data);
 }
 
 /**
diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
index 3991fd6e7..f4748d8f2 100644
--- a/src/include/lwip/tcp.h
+++ b/src/include/lwip/tcp.h
@@ -468,6 +468,8 @@ struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
 
 void             tcp_abort (struct tcp_pcb *pcb);
 err_t            tcp_close   (struct tcp_pcb *pcb);
+err_t            tcp_close_ext(struct tcp_pcb *pcb, u8_t rst_on_unacked_data);
+
 err_t            tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
 
 err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,