Merge pull request #10476 from tymoteuszblochmobica/closetcp

LWIP TCP socket close - disconnecting fix
pull/10625/head
Martin Kojtal 2019-05-21 09:34:45 +01:00 committed by GitHub
commit 02eaad45a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 2 deletions

View File

@ -50,9 +50,12 @@ void LWIP::socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len)
} }
LWIP &lwip = LWIP::get_instance(); LWIP &lwip = LWIP::get_instance();
lwip.adaptation.lock(); lwip.adaptation.lock();
if (eh == NETCONN_EVT_RCVPLUS && nc->state == NETCONN_NONE) {
lwip._event_flag.set(TCP_CLOSED_FLAG);
}
for (int i = 0; i < MEMP_NUM_NETCONN; i++) { for (int i = 0; i < MEMP_NUM_NETCONN; i++) {
if (lwip.arena[i].in_use if (lwip.arena[i].in_use
&& lwip.arena[i].conn == nc && lwip.arena[i].conn == nc
@ -292,7 +295,17 @@ nsapi_error_t LWIP::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
nsapi_error_t LWIP::socket_close(nsapi_socket_t handle) nsapi_error_t LWIP::socket_close(nsapi_socket_t handle)
{ {
struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle; struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;
#if LWIP_TCP
/* Check if TCP FSM is in ESTABLISHED state.
* Then give extra time for connection close handshaking until TIME_WAIT state.
* The purpose is to prevent eth/wifi driver stop and FIN ACK corrupt.
* This may happend if network interface disconnect follows immediately after socket_close.*/
if (NETCONNTYPE_GROUP(s->conn->type) == NETCONN_TCP && s->conn->pcb.tcp->state == ESTABLISHED) {
_event_flag.clear(TCP_CLOSED_FLAG);
netconn_shutdown(s->conn, false, true);
_event_flag.wait_any(TCP_CLOSED_FLAG, TCP_CLOSE_TIMEOUT);
}
#endif
netbuf_delete(s->buf); netbuf_delete(s->buf);
err_t err = netconn_delete(s->conn); err_t err = netconn_delete(s->conn);
arena_dealloc(s); arena_dealloc(s);

View File

@ -587,6 +587,8 @@ private:
LWIPMemoryManager memory_manager; LWIPMemoryManager memory_manager;
osThreadId tcpip_thread_id; osThreadId tcpip_thread_id;
rtos::Mutex adaptation; rtos::Mutex adaptation;
rtos::EventFlags _event_flag;
static const int TCP_CLOSED_FLAG = 0x4u;
}; };
#endif /* LWIPSTACK_H_ */ #endif /* LWIPSTACK_H_ */

View File

@ -246,6 +246,11 @@
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#ifdef MBED_CONF_TCP_CLOSE_TIMEOUT
#define TCP_CLOSE_TIMEOUT MBED_CONF_TCP_CLOSE_TIMEOUT
#else
#define TCP_CLOSE_TIMEOUT 1000
#endif
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif

View File

@ -100,6 +100,10 @@
"help": "Maximum number of retransmissions of SYN segments. Current default (used if null here) is set to 6 in opt.h", "help": "Maximum number of retransmissions of SYN segments. Current default (used if null here) is set to 6 in opt.h",
"value": null "value": null
}, },
"tcp-close-timeout": {
"help": "Maximum timeout (ms) for TCP close handshaking timeout",
"value": 1000
},
"pbuf-pool-size": { "pbuf-pool-size": {
"help": "Number of pbufs in pool - usually used for received packets, so this determines how much data can be buffered between reception and the application reading. If a driver uses PBUF_RAM for reception, less pool may be needed. Current default (used if null here) is set to 5 in lwipopts.h, unless overridden by target Ethernet drivers.", "help": "Number of pbufs in pool - usually used for received packets, so this determines how much data can be buffered between reception and the application reading. If a driver uses PBUF_RAM for reception, less pool may be needed. Current default (used if null here) is set to 5 in lwipopts.h, unless overridden by target Ethernet drivers.",
"value": null "value": null