weston-embedded/uC-TCP-IP

When in the FIN_WAIT_2 state and both NET_ERR_CFG_ARG_CHK_DBG_EN and NET_DBG_CFG_MEM_CLR_EN are disabled, there is a buffer leak.

wes-jmagasrevy opened this issue · 0 comments

In a nutshell, I was expecting the data that came in during the DATA_AVAIL state to be still processable and prompted this change at the end of NetTCP_RxPktConnHandlerFinWait2(). I also tested the change with NET_DBG_CFG_MEM_CLR_EN and NET_ERR_CFG_ARG_CHK_DBG_EN enabled.

The nitty-gritty:

When both NET_ERR_CFG_ARG_CHK_DBG_EN and NET_DBG_CFG_MEM_CLR_EN are DEF_DISABLED, there can be a situation where the EntriesLostCur and EntriesLostTot are incremented in the RxBufLargeStatPool statistics. This means that these buffers are irrecoverable because the function that frees these buffers (NetBuf_FreeHandler()) determined that the particular buffer has an address outside the buffer LIB memory pool's address range yielding a LIB_MEM_ERR_INVALID_BLK_ADDR_IN_POOL error.

I traced this issue back to a change in NetTCP_RxPktConnHandlerFinWait2() when the shutdown() function was being implemented. Adding the following conditional assignment: "*p_err = (data_avail) ? err_rtn : NET_TCP_ERR_CONN_DATA_NONE;" solved an issue at the application level during testing that allowed me to consume all the data in the Rx queue when the socket is shut down in the WR direction and our stack transitions from FIN_WAIT_2 to its non-standard DATA_AVAIL state.

Upon further inspection, I found out that our stack makes the decision to NOT process any incoming data in the DATA_AVAIL state and sends out a [RST] to let the other host know that the data it sent during (what it thought was) FIN_WAIT_2 was lost (See NetTCP_RxPktConnHandler() Note #3). Internally, the stack starts counting down from the generous (I call it egregious) 1800s User Timeout to allow the application to consume what's left in the receive queue and call close() to terminate it's end of the connection from an application level.

If we really want to fix this, we'd need to create a NetTCP_RxPktConnHandlerDataAvail() function that behaves like NetTCP_RxPktConnHandlerFinWait2() that queues received data when the connection is half-closed (i.e. shutdown in the WR direction) and doesn't just issue a RST when said data comes in.