Mon 21 Mar 2016 02:37:30 PM UTC, original submission:
lwip_netconn_do_close_internal() will keep the calling thread (which issued close()) blocked if a memory error is encountered.
This has been observed in the case where an application tries to close a TCP socket when the send buffer is full. When a socket's TCP buffer is full, we can't send a FIN packet (due to logic inside the TCP core).
The calling thread will stay blocked until LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT expires or we receive an ACK and space opens up in the send buffer, allowing use to send a FIN.
Here's the description of default close behavior in BSD sockets. Taken from Steven's, located under the section on SO_LINGER (7.5 Generic Socket Options):
"This option specifies how the close function operates for a connection-oriented protocol (e.g., for TCP and SCTP, but not for UDP). By default, close returns immediately, but if there is any data still remaining in the socket send buffer, the system will try to deliver the data to the peer."
In order to conform to the BSD behavior, we need a mechanism in LwIP to asynchronously initiate the closure again after encountering a memory failure in lwip_netconn_do_close_internal(). The calling thread would be unblocked in all execution paths and we could trigger the closure again in sent_tcp upon receiving an ACK. Other memory failures may need to be addressed appropriately. The LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT timeout would also apply if the memory condition never resolves itself
|