Assuming the MCU running FNET as a server, after successful connection with the client via TCP, then at some point, the client indicates to shutdown the connection by sending some messages to prepare to tear down the connection, then call API shutdown( clientSock, SHUT_WR)
. From the FNET server, as the client has not closed yet, calling to fnet_socket_shutdown()
shall not return error with the errno FNET_ERR_NOTCONN
.
How to reproduce:
The problem happens when the server receives the FIN packet, it changes the socket state sk->state = SS_CLOSING
. And tracing the problem from the fnet_socket_shutdown, it eventually called to _fnet_tcp_shutdown
, the problem seem to be the following code snippet:
static fnet_return_t _fnet_tcp_shutdown( fnet_socket_if_t *sk, fnet_sd_flags_t how )
{
/* If the socket is not connected, return.*/
if(sk->state != SS_CONNECTED) /* <<< I think this is where the problem happen, because the state at this point is SS_CLOSING */
{
_fnet_socket_set_error(sk, FNET_ERR_NOTCONN);
return FNET_ERR;
}
else
... /* some more code */
In my opinion, the SS_CLOSING meaning that the connection is still not reach the CLOSED state yet, thus, considering it is the error is not the expected behavior. In the normal case, it shall be able to run the another else branch and sending out the FIN packet and process, before we actually call the close
function. My proposal, if that is the valid finding, is changing that if condition to:
if(sk->state == SS_CLOSED)
{
/* Raise error */
}
else
{
/* process as usual */
}
I would like to know your opinion on this finding, as it seems the behavior is different from the document from this link https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2