@ActoryOu wrote:
if( ( bRxComplete == 0 ) || ( bTxDone == 0 ) )
{
/* Refusing FIN: Rx incomplete 1 optlen 4 tx done 1. */
FreeRTOS_debug_printf( ( "Refusing FIN[%u,%u]: RxCompl %d tx done %d\n",
pxSocket->usLocalPort,
pxSocket->u.xTCP.usRemotePort,
( int ) bRxComplete,
( int ) bTxDone ) );
xMayClose = pdFALSE;
+ pxTCPWindow->rx.ulCurrentSequenceNumber =
+ pxTCPWindow->rx.ulFINSequenceNumber + 1U;
}
Genius!
Thank you Actory! After your change, the RST packet will be accepted:
packet IP Contents
10270 x.5 ACK packet SEQ 697
10271 x.5 FIN packet SEQ 697
10272 x.10 TCP data 1460 bytes
10273 x.10 TCP data 1460 bytes
10274 x.5 RST pack SEQ 698 as expected
The FIN packet is handled as a 1-byte packet, and so ulCurrentSequenceNumber must be increased by 1.
Normally this happens in prvTCPHandleFin() :
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t * pxSocket,
const NetworkBufferDescriptor_t * pxNetworkBuffer )
{
if( ( ucTCPFlags & tcpTCP_FLAG_FIN ) != 0U )
{
pxTCPWindow->rx.ulCurrentSequenceNumber =
pxTCPWindow->rx.ulFINSequenceNumber + 1U;
}
}
… but prvTCPHandleFin() is only called when the stack agrees to close the connection.
In Mike’s PCAP file, the stack refused the FIN packet, and so it didn’t call prvTCPHandleFin(). And therefor, it also refused the RST packet with SEQ 698.
My suggestion was to let the client do a graceful shutdown (shutdown - wait - closesocket), which will prevent the whole problem.
Combining both changes will give the best results ![]()