tcp/close: Fix clean socket closure when lignering

If so_linger option enabled, we should preferably close the socket cleanly. Only
after timeout, we give up and close it with RTS.
This commit is contained in:
David Cermak
2022-09-15 12:36:31 +02:00
parent 8b599aa152
commit 316cfc17ce
4 changed files with 19 additions and 4 deletions
+7 -3
View File
@@ -897,7 +897,7 @@ netconn_drain(struct netconn *conn)
/* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
/* pcb might be set to NULL already by err_tcp() */ /* pcb might be set to NULL already by err_tcp() */
/* drain recvmbox */ /* drain recvmbox */
#if ESP_LWIP #if ESP_LWIP && LWIP_NETCONN_FULLDUPLEX
newconn->flags |= NETCONN_FLAG_MBOXINVALID; newconn->flags |= NETCONN_FLAG_MBOXINVALID;
#endif /* ESP_LWIP */ #endif /* ESP_LWIP */
netconn_drain(newconn); netconn_drain(newconn);
@@ -1007,7 +1007,7 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
err = ERR_OK; err = ERR_OK;
/* linger enabled/required at all? (i.e. is there untransmitted data left?) */ /* linger enabled/required at all? (i.e. is there untransmitted data left?) */
if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) { if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) {
if ((conn->linger == 0)) { if (conn->linger == 0) {
/* data left but linger prevents waiting */ /* data left but linger prevents waiting */
tcp_abort(tpcb); tcp_abort(tpcb);
tpcb = NULL; tpcb = NULL;
@@ -1031,7 +1031,11 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
if ((err == ERR_OK) && (tpcb != NULL)) if ((err == ERR_OK) && (tpcb != NULL))
#endif /* LWIP_SO_LINGER */ #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 { } else {
err = tcp_shutdown(tpcb, shut_rx, shut_tx); err = tcp_shutdown(tpcb, shut_rx, shut_tx);
+3
View File
@@ -96,6 +96,9 @@
#include "lwip/prot/dns.h" #include "lwip/prot/dns.h"
#include <string.h> #include <string.h>
#if ESP_DNS
#include <stdbool.h>
#endif
/** Random generator function to create random TXIDs and source ports for queries */ /** Random generator function to create random TXIDs and source ports for queries */
#ifndef DNS_RAND_TXID #ifndef DNS_RAND_TXID
+7 -1
View File
@@ -482,6 +482,12 @@ tcp_close_shutdown_fin(struct tcp_pcb *pcb)
*/ */
err_t err_t
tcp_close(struct tcp_pcb *pcb) 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(); LWIP_ASSERT_CORE_LOCKED();
@@ -495,7 +501,7 @@ tcp_close(struct tcp_pcb *pcb)
tcp_set_flags(pcb, TF_RXCLOSED); tcp_set_flags(pcb, TF_RXCLOSED);
} }
/* ... and close */ /* ... and close */
return tcp_close_shutdown(pcb, 1); return tcp_close_shutdown(pcb, rst_on_unacked_data);
} }
/** /**
+2
View File
@@ -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); void tcp_abort (struct tcp_pcb *pcb);
err_t tcp_close (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_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, err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,